History log of /openbsd-current/usr.sbin/smtpd/bounce.c
Revision (<<< Hide revision tags) (Show revision tags >>>) Date Author Comments
# 1.90 31-May-2023 op

add missing include of time.h

spotted after a report on OpenSMTPD-portable. While here include
sys/time.h in smtpd.h, as noted in event_init(3), since it includes
event.h.

ok millert@


# 1.89 15-May-2023 op

cast to '(long long)' instead of '(long long int)'

while here adjust the spacing in some of the touched lines.
requested by deraadt@, ok tb@


# 1.88 04-May-2023 chrisz

Be more economical with returning bodys in bounce messages
according to rfc3461 4.3

OK millert@


Revision tags: OPENBSD_7_3_BASE
# 1.87 08-Feb-2023 tb

usr.sbin: missing void to appease clang 15's -Wstrict-prototype.


Revision tags: OPENBSD_7_0_BASE OPENBSD_7_1_BASE OPENBSD_7_2_BASE
# 1.86 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.85 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.84 26-May-2021 eric

replaces calls to err(3)/errx(3) with fatal()/fatalx() from log.c
for code that runs in the daemon.

ok florian@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.83 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_7_BASE OPENBSD_6_8_BASE
# 1.82 24-Apr-2020 eric

strip trailing CRs at smtp level rather than io level

ok millert@


# 1.81 25-Nov-2019 eric

use crlf line-ending during the internal smtp session

ok gilles@ martijn@


Revision tags: OPENBSD_6_5_BASE OPENBSD_6_6_BASE
# 1.80 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


Revision tags: OPENBSD_6_4_BASE
# 1.79 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.78 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


Revision tags: OPENBSD_6_1_BASE OPENBSD_6_2_BASE OPENBSD_6_3_BASE
# 1.77 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.76 22-Nov-2016 eric

Normalize the io input buffer internally when reinstalling the io event, so
the caller doesn't have to bother with this.

ok gilles@ sunil@


# 1.75 21-Nov-2016 eric

replace calls to iobuf_*() functions with the corresponding io_*() wrappers.

ok sunil@ gilles@


# 1.74 20-Nov-2016 eric

add dedicated functions to set fd and callback on a struct io.
simplify io_init() prototype.

ok sunil@ gilles@


# 1.73 16-Nov-2016 eric

pass the user pointer as parameter to the io callback instead of having
the user dereference the io structure.

ok millert@ gilles@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.72 03-Feb-2016 sunil

Use "esc_class" to classify bounce type instead of "errorline" as
we no longer prepend status code to "errorline". Fixes mismatch
between DSN's subject line and its content.

Ok jung@ gilles@ millert@


# 1.71 24-Dec-2015 mmcc

more e-mail -> email


# 1.70 14-Dec-2015 sunil

Fix bad indents and whitespaces.

Ok jung@ gilles@


# 1.69 14-Dec-2015 jung

remove trailing whitespace

ok sunil gilles


# 1.68 23-Nov-2015 sunil

Restructure bounce content as a multi-part MIME message.
Content-Type header diff from Philipp Takacs <philipp<at>bureaucracy.de>

Ok gilles@ jung@


# 1.67 07-Oct-2015 millert

Use getline(3) rather than fgetln(3). OK gilles@


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.66 20-Jan-2015 deraadt

use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


Revision tags: OPENBSD_5_6_BASE
# 1.65 28-May-2014 daniel

remove an errant semicolon.

ok gilles@


# 1.64 19-Apr-2014 gilles

(void) cast snprintf() calls that cannot truncate


# 1.63 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


Revision tags: OPENBSD_5_5_BASE
# 1.62 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.61 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.60 03-Dec-2013 eric

warn when failing to enqueue an internal bounce.


# 1.59 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.58 26-Oct-2013 eric

%i -> %d in format strings


Revision tags: OPENBSD_5_4_BASE
# 1.57 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.56 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.55 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


Revision tags: OPENBSD_5_3_BASE
# 1.54 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.53 23-Nov-2012 eric

knf

ok gilles@


# 1.52 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.51 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.50 03-Oct-2012 chl

don't try to cope with iobuf_init() failure, make it fatal() instead.

from eric@ input

ok gilles@


# 1.49 02-Oct-2012 chl

check iobuf_init() return value.

ok gilles@ eric@


# 1.48 26-Sep-2012 chl

fix memory leak in case of fdopen() failure

ok eric@ gilles@


# 1.47 18-Aug-2012 eric

Limit the number of bounce sessions running at the same time. When
committed, a bounce is put on a runnable list of bounces. This list
is drained to enqueue as much bounces as possible within the limit.

This avoids DoS'ing the server when lots of bounces are enqueued at
startup.

While there, allow new envelopes to be added to a bounce until the
the very last moment (i.e. when the list of recipients is written).

ok gilles@ chl@


# 1.46 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.45 09-Aug-2012 eric

remove unused function and prototypes


# 1.44 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.43 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.42 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.41 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


Revision tags: OPENBSD_5_1_BASE
# 1.40 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.39 12-Jan-2012 eric

The status field in the envelope is confusing. Its only purpose is to
notify the runner of what happened with an envelope that has been
scheduled. It is not part of the state of the envelope, and it is not
even dumped. So it should only be set by mta/mda, checked by runner
to decide what to do with the envelope, and ignored everywhere else.

ok gilles@


# 1.38 11-Jan-2012 eric

Finally remove the queue_message_update() function which ended up
being only called by bounce sessions, so most of the code there was
actually useless. The envelope is directly deleted or updated at the
relevant place.

ok gilles@


# 1.37 27-Dec-2011 eric

Instead of using a separate "bounce" queue, create the bounce envelope
directly as an envelope of the bounced message, just like "regular"
envelopes.

ok gilles@


# 1.36 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.35 27-Oct-2011 chl

Use PRI{x,d}64 in format strings instead of %llx, %lld or %qd to print {u_,}int64_t or time_t

While there, cast some time_t to int64_t

These will fix build warnings for portable smptd

ok gilles@ eric@


# 1.34 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.33 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


Revision tags: OPENBSD_5_0_BASE
# 1.32 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.31 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.30 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.29 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.28 14-Apr-2011 gilles

fsqueue now provides fsqueue_message_fd_r() and fsqueue_message_fd_rw() to
obtain a read{-only,/write} descriptor to the message file.

make sure smtpd uses the new API everywhere it needs a fd, and kill the
many functions that were used until now.


# 1.27 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.26 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.25 21-Mar-2011 gilles

do not close msgfd in bounce_session(), it is closed by client_close()


Revision tags: OPENBSD_4_9_BASE
# 1.24 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.23 09-Oct-2010 gilles

missing from previous commit


# 1.22 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.21 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.20 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.19 19-May-2010 gilles

cleanup-only commit, removes unrequired includes, no functionnal change


# 1.18 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


Revision tags: OPENBSD_4_7_BASE
# 1.17 23-Dec-2009 jacekm

Implementation of RFC 2920 PIPELINING extension, client side only for now.

This restructures the client_* API internals significantly. The code becomes
pipelining in nature. All SMTP commands are put on the output queue and
dequeued as quickly as possible. Once dequeued, they're moved to the receive
queue so that replies can be matched with previous commands.

Dequeuing commands from the output queue halts when the count of commands
currently in-pipeline (``cmdi'') is equal to the command send window (``cmdw'').
There are three cmdw values useful in practice:

0 clear pipeline, ie. inhibit all future sends
1 disable pipelining, ie. use old ``one-request-one-reply`` mode
SIZE_T_MAX enable pipelining, ie. dequeue as many commands as possible

At the beginning of session cmdw is 1. When it is found that peer supports
PIPELINING, it grows to SIZE_T_MAX. After dequeing DATA it is again 1. After
sending QUIT it is 0.

Each command dequeued from the output queue becomes a buf in a msgbuf. The act
of combining multiple commands into a single send operation did not need to be
implemented: buf_write() already combines bufs using iovec and sends them at
once using sendmsg(2).

Tested by todd@ and oga@

"looks good" to gilles@


# 1.16 14-Dec-2009 jacekm

Handle 6yz code as permanent error.


# 1.15 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.14 12-Dec-2009 jacekm

When acting as a client do content reads from the disk progressively
as the remote accepts more data instead of doing one big read into
the memory in the beginning of session.


# 1.13 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.12 11-Nov-2009 chl

add missing headers needed by time()

ok jacekm@


# 1.11 05-Nov-2009 jsing

Include a Date: header in bounce messages.

ok jacekm@ gilles@


# 1.10 05-Nov-2009 jsing

Introduce a 6yz status code, used internally to report permanent errors.
The 1yz and 6yz status codes are now removed prior to reporting the status
message in bounce messages, which provides an easy way to distinguish
between local and remote status messages. Initial diff from jacekm@

ok gilles@ jacekm@


# 1.9 16-Sep-2009 jacekm

Free resources when bounce enqueue fails due to a timeout.


# 1.8 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.7 04-Sep-2009 jacekm

Fix scheduling of bounces that could not be delivered.
ok gilles@


# 1.6 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.5 06-Aug-2009 gilles

when writing a bounce, follow the same rule as for mta sessions and prepend
with a dot lines starting with a dot


# 1.4 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.3 06-Aug-2009 gilles

fix a typo in bounce message t -> to


# 1.2 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.1 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.87 08-Feb-2023 tb

usr.sbin: missing void to appease clang 15's -Wstrict-prototype.


Revision tags: OPENBSD_7_0_BASE OPENBSD_7_1_BASE OPENBSD_7_2_BASE
# 1.86 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.85 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.84 26-May-2021 eric

replaces calls to err(3)/errx(3) with fatal()/fatalx() from log.c
for code that runs in the daemon.

ok florian@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.83 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_7_BASE OPENBSD_6_8_BASE
# 1.82 24-Apr-2020 eric

strip trailing CRs at smtp level rather than io level

ok millert@


# 1.81 25-Nov-2019 eric

use crlf line-ending during the internal smtp session

ok gilles@ martijn@


Revision tags: OPENBSD_6_5_BASE OPENBSD_6_6_BASE
# 1.80 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


Revision tags: OPENBSD_6_4_BASE
# 1.79 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.78 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


Revision tags: OPENBSD_6_1_BASE OPENBSD_6_2_BASE OPENBSD_6_3_BASE
# 1.77 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.76 22-Nov-2016 eric

Normalize the io input buffer internally when reinstalling the io event, so
the caller doesn't have to bother with this.

ok gilles@ sunil@


# 1.75 21-Nov-2016 eric

replace calls to iobuf_*() functions with the corresponding io_*() wrappers.

ok sunil@ gilles@


# 1.74 20-Nov-2016 eric

add dedicated functions to set fd and callback on a struct io.
simplify io_init() prototype.

ok sunil@ gilles@


# 1.73 16-Nov-2016 eric

pass the user pointer as parameter to the io callback instead of having
the user dereference the io structure.

ok millert@ gilles@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.72 03-Feb-2016 sunil

Use "esc_class" to classify bounce type instead of "errorline" as
we no longer prepend status code to "errorline". Fixes mismatch
between DSN's subject line and its content.

Ok jung@ gilles@ millert@


# 1.71 24-Dec-2015 mmcc

more e-mail -> email


# 1.70 14-Dec-2015 sunil

Fix bad indents and whitespaces.

Ok jung@ gilles@


# 1.69 14-Dec-2015 jung

remove trailing whitespace

ok sunil gilles


# 1.68 23-Nov-2015 sunil

Restructure bounce content as a multi-part MIME message.
Content-Type header diff from Philipp Takacs <philipp<at>bureaucracy.de>

Ok gilles@ jung@


# 1.67 07-Oct-2015 millert

Use getline(3) rather than fgetln(3). OK gilles@


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.66 20-Jan-2015 deraadt

use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


Revision tags: OPENBSD_5_6_BASE
# 1.65 28-May-2014 daniel

remove an errant semicolon.

ok gilles@


# 1.64 19-Apr-2014 gilles

(void) cast snprintf() calls that cannot truncate


# 1.63 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


Revision tags: OPENBSD_5_5_BASE
# 1.62 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.61 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.60 03-Dec-2013 eric

warn when failing to enqueue an internal bounce.


# 1.59 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.58 26-Oct-2013 eric

%i -> %d in format strings


Revision tags: OPENBSD_5_4_BASE
# 1.57 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.56 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.55 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


Revision tags: OPENBSD_5_3_BASE
# 1.54 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.53 23-Nov-2012 eric

knf

ok gilles@


# 1.52 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.51 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.50 03-Oct-2012 chl

don't try to cope with iobuf_init() failure, make it fatal() instead.

from eric@ input

ok gilles@


# 1.49 02-Oct-2012 chl

check iobuf_init() return value.

ok gilles@ eric@


# 1.48 26-Sep-2012 chl

fix memory leak in case of fdopen() failure

ok eric@ gilles@


# 1.47 18-Aug-2012 eric

Limit the number of bounce sessions running at the same time. When
committed, a bounce is put on a runnable list of bounces. This list
is drained to enqueue as much bounces as possible within the limit.

This avoids DoS'ing the server when lots of bounces are enqueued at
startup.

While there, allow new envelopes to be added to a bounce until the
the very last moment (i.e. when the list of recipients is written).

ok gilles@ chl@


# 1.46 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.45 09-Aug-2012 eric

remove unused function and prototypes


# 1.44 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.43 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.42 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.41 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


Revision tags: OPENBSD_5_1_BASE
# 1.40 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.39 12-Jan-2012 eric

The status field in the envelope is confusing. Its only purpose is to
notify the runner of what happened with an envelope that has been
scheduled. It is not part of the state of the envelope, and it is not
even dumped. So it should only be set by mta/mda, checked by runner
to decide what to do with the envelope, and ignored everywhere else.

ok gilles@


# 1.38 11-Jan-2012 eric

Finally remove the queue_message_update() function which ended up
being only called by bounce sessions, so most of the code there was
actually useless. The envelope is directly deleted or updated at the
relevant place.

ok gilles@


# 1.37 27-Dec-2011 eric

Instead of using a separate "bounce" queue, create the bounce envelope
directly as an envelope of the bounced message, just like "regular"
envelopes.

ok gilles@


# 1.36 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.35 27-Oct-2011 chl

Use PRI{x,d}64 in format strings instead of %llx, %lld or %qd to print {u_,}int64_t or time_t

While there, cast some time_t to int64_t

These will fix build warnings for portable smptd

ok gilles@ eric@


# 1.34 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.33 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


Revision tags: OPENBSD_5_0_BASE
# 1.32 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.31 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.30 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.29 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.28 14-Apr-2011 gilles

fsqueue now provides fsqueue_message_fd_r() and fsqueue_message_fd_rw() to
obtain a read{-only,/write} descriptor to the message file.

make sure smtpd uses the new API everywhere it needs a fd, and kill the
many functions that were used until now.


# 1.27 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.26 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.25 21-Mar-2011 gilles

do not close msgfd in bounce_session(), it is closed by client_close()


Revision tags: OPENBSD_4_9_BASE
# 1.24 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.23 09-Oct-2010 gilles

missing from previous commit


# 1.22 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.21 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.20 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.19 19-May-2010 gilles

cleanup-only commit, removes unrequired includes, no functionnal change


# 1.18 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


Revision tags: OPENBSD_4_7_BASE
# 1.17 23-Dec-2009 jacekm

Implementation of RFC 2920 PIPELINING extension, client side only for now.

This restructures the client_* API internals significantly. The code becomes
pipelining in nature. All SMTP commands are put on the output queue and
dequeued as quickly as possible. Once dequeued, they're moved to the receive
queue so that replies can be matched with previous commands.

Dequeuing commands from the output queue halts when the count of commands
currently in-pipeline (``cmdi'') is equal to the command send window (``cmdw'').
There are three cmdw values useful in practice:

0 clear pipeline, ie. inhibit all future sends
1 disable pipelining, ie. use old ``one-request-one-reply`` mode
SIZE_T_MAX enable pipelining, ie. dequeue as many commands as possible

At the beginning of session cmdw is 1. When it is found that peer supports
PIPELINING, it grows to SIZE_T_MAX. After dequeing DATA it is again 1. After
sending QUIT it is 0.

Each command dequeued from the output queue becomes a buf in a msgbuf. The act
of combining multiple commands into a single send operation did not need to be
implemented: buf_write() already combines bufs using iovec and sends them at
once using sendmsg(2).

Tested by todd@ and oga@

"looks good" to gilles@


# 1.16 14-Dec-2009 jacekm

Handle 6yz code as permanent error.


# 1.15 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.14 12-Dec-2009 jacekm

When acting as a client do content reads from the disk progressively
as the remote accepts more data instead of doing one big read into
the memory in the beginning of session.


# 1.13 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.12 11-Nov-2009 chl

add missing headers needed by time()

ok jacekm@


# 1.11 05-Nov-2009 jsing

Include a Date: header in bounce messages.

ok jacekm@ gilles@


# 1.10 05-Nov-2009 jsing

Introduce a 6yz status code, used internally to report permanent errors.
The 1yz and 6yz status codes are now removed prior to reporting the status
message in bounce messages, which provides an easy way to distinguish
between local and remote status messages. Initial diff from jacekm@

ok gilles@ jacekm@


# 1.9 16-Sep-2009 jacekm

Free resources when bounce enqueue fails due to a timeout.


# 1.8 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.7 04-Sep-2009 jacekm

Fix scheduling of bounces that could not be delivered.
ok gilles@


# 1.6 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.5 06-Aug-2009 gilles

when writing a bounce, follow the same rule as for mta sessions and prepend
with a dot lines starting with a dot


# 1.4 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.3 06-Aug-2009 gilles

fix a typo in bounce message t -> to


# 1.2 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.1 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.86 28-Jul-2021 benno

add format attribute to vaararg functions.
millert@ thinks its useful.


# 1.85 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.84 26-May-2021 eric

replaces calls to err(3)/errx(3) with fatal()/fatalx() from log.c
for code that runs in the daemon.

ok florian@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.83 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_7_BASE OPENBSD_6_8_BASE
# 1.82 24-Apr-2020 eric

strip trailing CRs at smtp level rather than io level

ok millert@


# 1.81 25-Nov-2019 eric

use crlf line-ending during the internal smtp session

ok gilles@ martijn@


Revision tags: OPENBSD_6_5_BASE OPENBSD_6_6_BASE
# 1.80 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


Revision tags: OPENBSD_6_4_BASE
# 1.79 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.78 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


Revision tags: OPENBSD_6_1_BASE OPENBSD_6_2_BASE OPENBSD_6_3_BASE
# 1.77 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.76 22-Nov-2016 eric

Normalize the io input buffer internally when reinstalling the io event, so
the caller doesn't have to bother with this.

ok gilles@ sunil@


# 1.75 21-Nov-2016 eric

replace calls to iobuf_*() functions with the corresponding io_*() wrappers.

ok sunil@ gilles@


# 1.74 20-Nov-2016 eric

add dedicated functions to set fd and callback on a struct io.
simplify io_init() prototype.

ok sunil@ gilles@


# 1.73 16-Nov-2016 eric

pass the user pointer as parameter to the io callback instead of having
the user dereference the io structure.

ok millert@ gilles@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.72 03-Feb-2016 sunil

Use "esc_class" to classify bounce type instead of "errorline" as
we no longer prepend status code to "errorline". Fixes mismatch
between DSN's subject line and its content.

Ok jung@ gilles@ millert@


# 1.71 24-Dec-2015 mmcc

more e-mail -> email


# 1.70 14-Dec-2015 sunil

Fix bad indents and whitespaces.

Ok jung@ gilles@


# 1.69 14-Dec-2015 jung

remove trailing whitespace

ok sunil gilles


# 1.68 23-Nov-2015 sunil

Restructure bounce content as a multi-part MIME message.
Content-Type header diff from Philipp Takacs <philipp<at>bureaucracy.de>

Ok gilles@ jung@


# 1.67 07-Oct-2015 millert

Use getline(3) rather than fgetln(3). OK gilles@


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.66 20-Jan-2015 deraadt

use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


Revision tags: OPENBSD_5_6_BASE
# 1.65 28-May-2014 daniel

remove an errant semicolon.

ok gilles@


# 1.64 19-Apr-2014 gilles

(void) cast snprintf() calls that cannot truncate


# 1.63 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


Revision tags: OPENBSD_5_5_BASE
# 1.62 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.61 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.60 03-Dec-2013 eric

warn when failing to enqueue an internal bounce.


# 1.59 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.58 26-Oct-2013 eric

%i -> %d in format strings


Revision tags: OPENBSD_5_4_BASE
# 1.57 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.56 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.55 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


Revision tags: OPENBSD_5_3_BASE
# 1.54 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.53 23-Nov-2012 eric

knf

ok gilles@


# 1.52 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.51 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.50 03-Oct-2012 chl

don't try to cope with iobuf_init() failure, make it fatal() instead.

from eric@ input

ok gilles@


# 1.49 02-Oct-2012 chl

check iobuf_init() return value.

ok gilles@ eric@


# 1.48 26-Sep-2012 chl

fix memory leak in case of fdopen() failure

ok eric@ gilles@


# 1.47 18-Aug-2012 eric

Limit the number of bounce sessions running at the same time. When
committed, a bounce is put on a runnable list of bounces. This list
is drained to enqueue as much bounces as possible within the limit.

This avoids DoS'ing the server when lots of bounces are enqueued at
startup.

While there, allow new envelopes to be added to a bounce until the
the very last moment (i.e. when the list of recipients is written).

ok gilles@ chl@


# 1.46 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.45 09-Aug-2012 eric

remove unused function and prototypes


# 1.44 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.43 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.42 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.41 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


Revision tags: OPENBSD_5_1_BASE
# 1.40 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.39 12-Jan-2012 eric

The status field in the envelope is confusing. Its only purpose is to
notify the runner of what happened with an envelope that has been
scheduled. It is not part of the state of the envelope, and it is not
even dumped. So it should only be set by mta/mda, checked by runner
to decide what to do with the envelope, and ignored everywhere else.

ok gilles@


# 1.38 11-Jan-2012 eric

Finally remove the queue_message_update() function which ended up
being only called by bounce sessions, so most of the code there was
actually useless. The envelope is directly deleted or updated at the
relevant place.

ok gilles@


# 1.37 27-Dec-2011 eric

Instead of using a separate "bounce" queue, create the bounce envelope
directly as an envelope of the bounced message, just like "regular"
envelopes.

ok gilles@


# 1.36 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.35 27-Oct-2011 chl

Use PRI{x,d}64 in format strings instead of %llx, %lld or %qd to print {u_,}int64_t or time_t

While there, cast some time_t to int64_t

These will fix build warnings for portable smptd

ok gilles@ eric@


# 1.34 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.33 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


Revision tags: OPENBSD_5_0_BASE
# 1.32 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.31 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.30 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.29 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.28 14-Apr-2011 gilles

fsqueue now provides fsqueue_message_fd_r() and fsqueue_message_fd_rw() to
obtain a read{-only,/write} descriptor to the message file.

make sure smtpd uses the new API everywhere it needs a fd, and kill the
many functions that were used until now.


# 1.27 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.26 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.25 21-Mar-2011 gilles

do not close msgfd in bounce_session(), it is closed by client_close()


Revision tags: OPENBSD_4_9_BASE
# 1.24 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.23 09-Oct-2010 gilles

missing from previous commit


# 1.22 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.21 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.20 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.19 19-May-2010 gilles

cleanup-only commit, removes unrequired includes, no functionnal change


# 1.18 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


Revision tags: OPENBSD_4_7_BASE
# 1.17 23-Dec-2009 jacekm

Implementation of RFC 2920 PIPELINING extension, client side only for now.

This restructures the client_* API internals significantly. The code becomes
pipelining in nature. All SMTP commands are put on the output queue and
dequeued as quickly as possible. Once dequeued, they're moved to the receive
queue so that replies can be matched with previous commands.

Dequeuing commands from the output queue halts when the count of commands
currently in-pipeline (``cmdi'') is equal to the command send window (``cmdw'').
There are three cmdw values useful in practice:

0 clear pipeline, ie. inhibit all future sends
1 disable pipelining, ie. use old ``one-request-one-reply`` mode
SIZE_T_MAX enable pipelining, ie. dequeue as many commands as possible

At the beginning of session cmdw is 1. When it is found that peer supports
PIPELINING, it grows to SIZE_T_MAX. After dequeing DATA it is again 1. After
sending QUIT it is 0.

Each command dequeued from the output queue becomes a buf in a msgbuf. The act
of combining multiple commands into a single send operation did not need to be
implemented: buf_write() already combines bufs using iovec and sends them at
once using sendmsg(2).

Tested by todd@ and oga@

"looks good" to gilles@


# 1.16 14-Dec-2009 jacekm

Handle 6yz code as permanent error.


# 1.15 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.14 12-Dec-2009 jacekm

When acting as a client do content reads from the disk progressively
as the remote accepts more data instead of doing one big read into
the memory in the beginning of session.


# 1.13 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.12 11-Nov-2009 chl

add missing headers needed by time()

ok jacekm@


# 1.11 05-Nov-2009 jsing

Include a Date: header in bounce messages.

ok jacekm@ gilles@


# 1.10 05-Nov-2009 jsing

Introduce a 6yz status code, used internally to report permanent errors.
The 1yz and 6yz status codes are now removed prior to reporting the status
message in bounce messages, which provides an easy way to distinguish
between local and remote status messages. Initial diff from jacekm@

ok gilles@ jacekm@


# 1.9 16-Sep-2009 jacekm

Free resources when bounce enqueue fails due to a timeout.


# 1.8 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.7 04-Sep-2009 jacekm

Fix scheduling of bounces that could not be delivered.
ok gilles@


# 1.6 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.5 06-Aug-2009 gilles

when writing a bounce, follow the same rule as for mta sessions and prepend
with a dot lines starting with a dot


# 1.4 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.3 06-Aug-2009 gilles

fix a typo in bounce message t -> to


# 1.2 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.1 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.85 14-Jun-2021 eric

add required headers for smtpd.h and remove unnecessary ones in other files.

ok jung@


# 1.84 26-May-2021 eric

replaces calls to err(3)/errx(3) with fatal()/fatalx() from log.c
for code that runs in the daemon.

ok florian@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.83 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_7_BASE OPENBSD_6_8_BASE
# 1.82 24-Apr-2020 eric

strip trailing CRs at smtp level rather than io level

ok millert@


# 1.81 25-Nov-2019 eric

use crlf line-ending during the internal smtp session

ok gilles@ martijn@


Revision tags: OPENBSD_6_5_BASE OPENBSD_6_6_BASE
# 1.80 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


Revision tags: OPENBSD_6_4_BASE
# 1.79 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.78 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


Revision tags: OPENBSD_6_1_BASE OPENBSD_6_2_BASE OPENBSD_6_3_BASE
# 1.77 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.76 22-Nov-2016 eric

Normalize the io input buffer internally when reinstalling the io event, so
the caller doesn't have to bother with this.

ok gilles@ sunil@


# 1.75 21-Nov-2016 eric

replace calls to iobuf_*() functions with the corresponding io_*() wrappers.

ok sunil@ gilles@


# 1.74 20-Nov-2016 eric

add dedicated functions to set fd and callback on a struct io.
simplify io_init() prototype.

ok sunil@ gilles@


# 1.73 16-Nov-2016 eric

pass the user pointer as parameter to the io callback instead of having
the user dereference the io structure.

ok millert@ gilles@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.72 03-Feb-2016 sunil

Use "esc_class" to classify bounce type instead of "errorline" as
we no longer prepend status code to "errorline". Fixes mismatch
between DSN's subject line and its content.

Ok jung@ gilles@ millert@


# 1.71 24-Dec-2015 mmcc

more e-mail -> email


# 1.70 14-Dec-2015 sunil

Fix bad indents and whitespaces.

Ok jung@ gilles@


# 1.69 14-Dec-2015 jung

remove trailing whitespace

ok sunil gilles


# 1.68 23-Nov-2015 sunil

Restructure bounce content as a multi-part MIME message.
Content-Type header diff from Philipp Takacs <philipp<at>bureaucracy.de>

Ok gilles@ jung@


# 1.67 07-Oct-2015 millert

Use getline(3) rather than fgetln(3). OK gilles@


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.66 20-Jan-2015 deraadt

use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


Revision tags: OPENBSD_5_6_BASE
# 1.65 28-May-2014 daniel

remove an errant semicolon.

ok gilles@


# 1.64 19-Apr-2014 gilles

(void) cast snprintf() calls that cannot truncate


# 1.63 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


Revision tags: OPENBSD_5_5_BASE
# 1.62 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.61 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.60 03-Dec-2013 eric

warn when failing to enqueue an internal bounce.


# 1.59 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.58 26-Oct-2013 eric

%i -> %d in format strings


Revision tags: OPENBSD_5_4_BASE
# 1.57 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.56 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.55 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


Revision tags: OPENBSD_5_3_BASE
# 1.54 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.53 23-Nov-2012 eric

knf

ok gilles@


# 1.52 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.51 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.50 03-Oct-2012 chl

don't try to cope with iobuf_init() failure, make it fatal() instead.

from eric@ input

ok gilles@


# 1.49 02-Oct-2012 chl

check iobuf_init() return value.

ok gilles@ eric@


# 1.48 26-Sep-2012 chl

fix memory leak in case of fdopen() failure

ok eric@ gilles@


# 1.47 18-Aug-2012 eric

Limit the number of bounce sessions running at the same time. When
committed, a bounce is put on a runnable list of bounces. This list
is drained to enqueue as much bounces as possible within the limit.

This avoids DoS'ing the server when lots of bounces are enqueued at
startup.

While there, allow new envelopes to be added to a bounce until the
the very last moment (i.e. when the list of recipients is written).

ok gilles@ chl@


# 1.46 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.45 09-Aug-2012 eric

remove unused function and prototypes


# 1.44 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.43 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.42 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.41 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


Revision tags: OPENBSD_5_1_BASE
# 1.40 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.39 12-Jan-2012 eric

The status field in the envelope is confusing. Its only purpose is to
notify the runner of what happened with an envelope that has been
scheduled. It is not part of the state of the envelope, and it is not
even dumped. So it should only be set by mta/mda, checked by runner
to decide what to do with the envelope, and ignored everywhere else.

ok gilles@


# 1.38 11-Jan-2012 eric

Finally remove the queue_message_update() function which ended up
being only called by bounce sessions, so most of the code there was
actually useless. The envelope is directly deleted or updated at the
relevant place.

ok gilles@


# 1.37 27-Dec-2011 eric

Instead of using a separate "bounce" queue, create the bounce envelope
directly as an envelope of the bounced message, just like "regular"
envelopes.

ok gilles@


# 1.36 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.35 27-Oct-2011 chl

Use PRI{x,d}64 in format strings instead of %llx, %lld or %qd to print {u_,}int64_t or time_t

While there, cast some time_t to int64_t

These will fix build warnings for portable smptd

ok gilles@ eric@


# 1.34 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.33 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


Revision tags: OPENBSD_5_0_BASE
# 1.32 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.31 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.30 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.29 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.28 14-Apr-2011 gilles

fsqueue now provides fsqueue_message_fd_r() and fsqueue_message_fd_rw() to
obtain a read{-only,/write} descriptor to the message file.

make sure smtpd uses the new API everywhere it needs a fd, and kill the
many functions that were used until now.


# 1.27 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.26 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.25 21-Mar-2011 gilles

do not close msgfd in bounce_session(), it is closed by client_close()


Revision tags: OPENBSD_4_9_BASE
# 1.24 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.23 09-Oct-2010 gilles

missing from previous commit


# 1.22 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.21 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.20 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.19 19-May-2010 gilles

cleanup-only commit, removes unrequired includes, no functionnal change


# 1.18 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


Revision tags: OPENBSD_4_7_BASE
# 1.17 23-Dec-2009 jacekm

Implementation of RFC 2920 PIPELINING extension, client side only for now.

This restructures the client_* API internals significantly. The code becomes
pipelining in nature. All SMTP commands are put on the output queue and
dequeued as quickly as possible. Once dequeued, they're moved to the receive
queue so that replies can be matched with previous commands.

Dequeuing commands from the output queue halts when the count of commands
currently in-pipeline (``cmdi'') is equal to the command send window (``cmdw'').
There are three cmdw values useful in practice:

0 clear pipeline, ie. inhibit all future sends
1 disable pipelining, ie. use old ``one-request-one-reply`` mode
SIZE_T_MAX enable pipelining, ie. dequeue as many commands as possible

At the beginning of session cmdw is 1. When it is found that peer supports
PIPELINING, it grows to SIZE_T_MAX. After dequeing DATA it is again 1. After
sending QUIT it is 0.

Each command dequeued from the output queue becomes a buf in a msgbuf. The act
of combining multiple commands into a single send operation did not need to be
implemented: buf_write() already combines bufs using iovec and sends them at
once using sendmsg(2).

Tested by todd@ and oga@

"looks good" to gilles@


# 1.16 14-Dec-2009 jacekm

Handle 6yz code as permanent error.


# 1.15 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.14 12-Dec-2009 jacekm

When acting as a client do content reads from the disk progressively
as the remote accepts more data instead of doing one big read into
the memory in the beginning of session.


# 1.13 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.12 11-Nov-2009 chl

add missing headers needed by time()

ok jacekm@


# 1.11 05-Nov-2009 jsing

Include a Date: header in bounce messages.

ok jacekm@ gilles@


# 1.10 05-Nov-2009 jsing

Introduce a 6yz status code, used internally to report permanent errors.
The 1yz and 6yz status codes are now removed prior to reporting the status
message in bounce messages, which provides an easy way to distinguish
between local and remote status messages. Initial diff from jacekm@

ok gilles@ jacekm@


# 1.9 16-Sep-2009 jacekm

Free resources when bounce enqueue fails due to a timeout.


# 1.8 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.7 04-Sep-2009 jacekm

Fix scheduling of bounces that could not be delivered.
ok gilles@


# 1.6 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.5 06-Aug-2009 gilles

when writing a bounce, follow the same rule as for mta sessions and prepend
with a dot lines starting with a dot


# 1.4 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.3 06-Aug-2009 gilles

fix a typo in bounce message t -> to


# 1.2 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.1 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.84 26-May-2021 eric

replaces calls to err(3)/errx(3) with fatal()/fatalx() from log.c
for code that runs in the daemon.

ok florian@ millert@


Revision tags: OPENBSD_6_9_BASE
# 1.83 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_7_BASE OPENBSD_6_8_BASE
# 1.82 24-Apr-2020 eric

strip trailing CRs at smtp level rather than io level

ok millert@


# 1.81 25-Nov-2019 eric

use crlf line-ending during the internal smtp session

ok gilles@ martijn@


Revision tags: OPENBSD_6_5_BASE OPENBSD_6_6_BASE
# 1.80 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


Revision tags: OPENBSD_6_4_BASE
# 1.79 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.78 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


Revision tags: OPENBSD_6_1_BASE OPENBSD_6_2_BASE OPENBSD_6_3_BASE
# 1.77 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.76 22-Nov-2016 eric

Normalize the io input buffer internally when reinstalling the io event, so
the caller doesn't have to bother with this.

ok gilles@ sunil@


# 1.75 21-Nov-2016 eric

replace calls to iobuf_*() functions with the corresponding io_*() wrappers.

ok sunil@ gilles@


# 1.74 20-Nov-2016 eric

add dedicated functions to set fd and callback on a struct io.
simplify io_init() prototype.

ok sunil@ gilles@


# 1.73 16-Nov-2016 eric

pass the user pointer as parameter to the io callback instead of having
the user dereference the io structure.

ok millert@ gilles@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.72 03-Feb-2016 sunil

Use "esc_class" to classify bounce type instead of "errorline" as
we no longer prepend status code to "errorline". Fixes mismatch
between DSN's subject line and its content.

Ok jung@ gilles@ millert@


# 1.71 24-Dec-2015 mmcc

more e-mail -> email


# 1.70 14-Dec-2015 sunil

Fix bad indents and whitespaces.

Ok jung@ gilles@


# 1.69 14-Dec-2015 jung

remove trailing whitespace

ok sunil gilles


# 1.68 23-Nov-2015 sunil

Restructure bounce content as a multi-part MIME message.
Content-Type header diff from Philipp Takacs <philipp<at>bureaucracy.de>

Ok gilles@ jung@


# 1.67 07-Oct-2015 millert

Use getline(3) rather than fgetln(3). OK gilles@


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.66 20-Jan-2015 deraadt

use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


Revision tags: OPENBSD_5_6_BASE
# 1.65 28-May-2014 daniel

remove an errant semicolon.

ok gilles@


# 1.64 19-Apr-2014 gilles

(void) cast snprintf() calls that cannot truncate


# 1.63 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


Revision tags: OPENBSD_5_5_BASE
# 1.62 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.61 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.60 03-Dec-2013 eric

warn when failing to enqueue an internal bounce.


# 1.59 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.58 26-Oct-2013 eric

%i -> %d in format strings


Revision tags: OPENBSD_5_4_BASE
# 1.57 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.56 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.55 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


Revision tags: OPENBSD_5_3_BASE
# 1.54 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.53 23-Nov-2012 eric

knf

ok gilles@


# 1.52 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.51 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.50 03-Oct-2012 chl

don't try to cope with iobuf_init() failure, make it fatal() instead.

from eric@ input

ok gilles@


# 1.49 02-Oct-2012 chl

check iobuf_init() return value.

ok gilles@ eric@


# 1.48 26-Sep-2012 chl

fix memory leak in case of fdopen() failure

ok eric@ gilles@


# 1.47 18-Aug-2012 eric

Limit the number of bounce sessions running at the same time. When
committed, a bounce is put on a runnable list of bounces. This list
is drained to enqueue as much bounces as possible within the limit.

This avoids DoS'ing the server when lots of bounces are enqueued at
startup.

While there, allow new envelopes to be added to a bounce until the
the very last moment (i.e. when the list of recipients is written).

ok gilles@ chl@


# 1.46 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.45 09-Aug-2012 eric

remove unused function and prototypes


# 1.44 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.43 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.42 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.41 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


Revision tags: OPENBSD_5_1_BASE
# 1.40 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.39 12-Jan-2012 eric

The status field in the envelope is confusing. Its only purpose is to
notify the runner of what happened with an envelope that has been
scheduled. It is not part of the state of the envelope, and it is not
even dumped. So it should only be set by mta/mda, checked by runner
to decide what to do with the envelope, and ignored everywhere else.

ok gilles@


# 1.38 11-Jan-2012 eric

Finally remove the queue_message_update() function which ended up
being only called by bounce sessions, so most of the code there was
actually useless. The envelope is directly deleted or updated at the
relevant place.

ok gilles@


# 1.37 27-Dec-2011 eric

Instead of using a separate "bounce" queue, create the bounce envelope
directly as an envelope of the bounced message, just like "regular"
envelopes.

ok gilles@


# 1.36 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.35 27-Oct-2011 chl

Use PRI{x,d}64 in format strings instead of %llx, %lld or %qd to print {u_,}int64_t or time_t

While there, cast some time_t to int64_t

These will fix build warnings for portable smptd

ok gilles@ eric@


# 1.34 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.33 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


Revision tags: OPENBSD_5_0_BASE
# 1.32 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.31 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.30 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.29 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.28 14-Apr-2011 gilles

fsqueue now provides fsqueue_message_fd_r() and fsqueue_message_fd_rw() to
obtain a read{-only,/write} descriptor to the message file.

make sure smtpd uses the new API everywhere it needs a fd, and kill the
many functions that were used until now.


# 1.27 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.26 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.25 21-Mar-2011 gilles

do not close msgfd in bounce_session(), it is closed by client_close()


Revision tags: OPENBSD_4_9_BASE
# 1.24 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.23 09-Oct-2010 gilles

missing from previous commit


# 1.22 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.21 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.20 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.19 19-May-2010 gilles

cleanup-only commit, removes unrequired includes, no functionnal change


# 1.18 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


Revision tags: OPENBSD_4_7_BASE
# 1.17 23-Dec-2009 jacekm

Implementation of RFC 2920 PIPELINING extension, client side only for now.

This restructures the client_* API internals significantly. The code becomes
pipelining in nature. All SMTP commands are put on the output queue and
dequeued as quickly as possible. Once dequeued, they're moved to the receive
queue so that replies can be matched with previous commands.

Dequeuing commands from the output queue halts when the count of commands
currently in-pipeline (``cmdi'') is equal to the command send window (``cmdw'').
There are three cmdw values useful in practice:

0 clear pipeline, ie. inhibit all future sends
1 disable pipelining, ie. use old ``one-request-one-reply`` mode
SIZE_T_MAX enable pipelining, ie. dequeue as many commands as possible

At the beginning of session cmdw is 1. When it is found that peer supports
PIPELINING, it grows to SIZE_T_MAX. After dequeing DATA it is again 1. After
sending QUIT it is 0.

Each command dequeued from the output queue becomes a buf in a msgbuf. The act
of combining multiple commands into a single send operation did not need to be
implemented: buf_write() already combines bufs using iovec and sends them at
once using sendmsg(2).

Tested by todd@ and oga@

"looks good" to gilles@


# 1.16 14-Dec-2009 jacekm

Handle 6yz code as permanent error.


# 1.15 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.14 12-Dec-2009 jacekm

When acting as a client do content reads from the disk progressively
as the remote accepts more data instead of doing one big read into
the memory in the beginning of session.


# 1.13 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.12 11-Nov-2009 chl

add missing headers needed by time()

ok jacekm@


# 1.11 05-Nov-2009 jsing

Include a Date: header in bounce messages.

ok jacekm@ gilles@


# 1.10 05-Nov-2009 jsing

Introduce a 6yz status code, used internally to report permanent errors.
The 1yz and 6yz status codes are now removed prior to reporting the status
message in bounce messages, which provides an easy way to distinguish
between local and remote status messages. Initial diff from jacekm@

ok gilles@ jacekm@


# 1.9 16-Sep-2009 jacekm

Free resources when bounce enqueue fails due to a timeout.


# 1.8 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.7 04-Sep-2009 jacekm

Fix scheduling of bounces that could not be delivered.
ok gilles@


# 1.6 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.5 06-Aug-2009 gilles

when writing a bounce, follow the same rule as for mta sessions and prepend
with a dot lines starting with a dot


# 1.4 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.3 06-Aug-2009 gilles

fix a typo in bounce message t -> to


# 1.2 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.1 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.83 31-Dec-2020 martijn

Rename the pony process to dispatcher and klondike to crypto.

From gilles@
OK millert@ giovanni@


Revision tags: OPENBSD_6_7_BASE OPENBSD_6_8_BASE
# 1.82 24-Apr-2020 eric

strip trailing CRs at smtp level rather than io level

ok millert@


# 1.81 25-Nov-2019 eric

use crlf line-ending during the internal smtp session

ok gilles@ martijn@


Revision tags: OPENBSD_6_5_BASE OPENBSD_6_6_BASE
# 1.80 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


Revision tags: OPENBSD_6_4_BASE
# 1.79 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.78 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


Revision tags: OPENBSD_6_1_BASE OPENBSD_6_2_BASE OPENBSD_6_3_BASE
# 1.77 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.76 22-Nov-2016 eric

Normalize the io input buffer internally when reinstalling the io event, so
the caller doesn't have to bother with this.

ok gilles@ sunil@


# 1.75 21-Nov-2016 eric

replace calls to iobuf_*() functions with the corresponding io_*() wrappers.

ok sunil@ gilles@


# 1.74 20-Nov-2016 eric

add dedicated functions to set fd and callback on a struct io.
simplify io_init() prototype.

ok sunil@ gilles@


# 1.73 16-Nov-2016 eric

pass the user pointer as parameter to the io callback instead of having
the user dereference the io structure.

ok millert@ gilles@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.72 03-Feb-2016 sunil

Use "esc_class" to classify bounce type instead of "errorline" as
we no longer prepend status code to "errorline". Fixes mismatch
between DSN's subject line and its content.

Ok jung@ gilles@ millert@


# 1.71 24-Dec-2015 mmcc

more e-mail -> email


# 1.70 14-Dec-2015 sunil

Fix bad indents and whitespaces.

Ok jung@ gilles@


# 1.69 14-Dec-2015 jung

remove trailing whitespace

ok sunil gilles


# 1.68 23-Nov-2015 sunil

Restructure bounce content as a multi-part MIME message.
Content-Type header diff from Philipp Takacs <philipp<at>bureaucracy.de>

Ok gilles@ jung@


# 1.67 07-Oct-2015 millert

Use getline(3) rather than fgetln(3). OK gilles@


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.66 20-Jan-2015 deraadt

use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


Revision tags: OPENBSD_5_6_BASE
# 1.65 28-May-2014 daniel

remove an errant semicolon.

ok gilles@


# 1.64 19-Apr-2014 gilles

(void) cast snprintf() calls that cannot truncate


# 1.63 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


Revision tags: OPENBSD_5_5_BASE
# 1.62 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.61 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.60 03-Dec-2013 eric

warn when failing to enqueue an internal bounce.


# 1.59 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.58 26-Oct-2013 eric

%i -> %d in format strings


Revision tags: OPENBSD_5_4_BASE
# 1.57 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.56 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.55 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


Revision tags: OPENBSD_5_3_BASE
# 1.54 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.53 23-Nov-2012 eric

knf

ok gilles@


# 1.52 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.51 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.50 03-Oct-2012 chl

don't try to cope with iobuf_init() failure, make it fatal() instead.

from eric@ input

ok gilles@


# 1.49 02-Oct-2012 chl

check iobuf_init() return value.

ok gilles@ eric@


# 1.48 26-Sep-2012 chl

fix memory leak in case of fdopen() failure

ok eric@ gilles@


# 1.47 18-Aug-2012 eric

Limit the number of bounce sessions running at the same time. When
committed, a bounce is put on a runnable list of bounces. This list
is drained to enqueue as much bounces as possible within the limit.

This avoids DoS'ing the server when lots of bounces are enqueued at
startup.

While there, allow new envelopes to be added to a bounce until the
the very last moment (i.e. when the list of recipients is written).

ok gilles@ chl@


# 1.46 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.45 09-Aug-2012 eric

remove unused function and prototypes


# 1.44 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.43 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.42 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.41 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


Revision tags: OPENBSD_5_1_BASE
# 1.40 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.39 12-Jan-2012 eric

The status field in the envelope is confusing. Its only purpose is to
notify the runner of what happened with an envelope that has been
scheduled. It is not part of the state of the envelope, and it is not
even dumped. So it should only be set by mta/mda, checked by runner
to decide what to do with the envelope, and ignored everywhere else.

ok gilles@


# 1.38 11-Jan-2012 eric

Finally remove the queue_message_update() function which ended up
being only called by bounce sessions, so most of the code there was
actually useless. The envelope is directly deleted or updated at the
relevant place.

ok gilles@


# 1.37 27-Dec-2011 eric

Instead of using a separate "bounce" queue, create the bounce envelope
directly as an envelope of the bounced message, just like "regular"
envelopes.

ok gilles@


# 1.36 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.35 27-Oct-2011 chl

Use PRI{x,d}64 in format strings instead of %llx, %lld or %qd to print {u_,}int64_t or time_t

While there, cast some time_t to int64_t

These will fix build warnings for portable smptd

ok gilles@ eric@


# 1.34 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.33 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


Revision tags: OPENBSD_5_0_BASE
# 1.32 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.31 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.30 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.29 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.28 14-Apr-2011 gilles

fsqueue now provides fsqueue_message_fd_r() and fsqueue_message_fd_rw() to
obtain a read{-only,/write} descriptor to the message file.

make sure smtpd uses the new API everywhere it needs a fd, and kill the
many functions that were used until now.


# 1.27 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.26 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.25 21-Mar-2011 gilles

do not close msgfd in bounce_session(), it is closed by client_close()


Revision tags: OPENBSD_4_9_BASE
# 1.24 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.23 09-Oct-2010 gilles

missing from previous commit


# 1.22 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.21 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.20 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.19 19-May-2010 gilles

cleanup-only commit, removes unrequired includes, no functionnal change


# 1.18 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


Revision tags: OPENBSD_4_7_BASE
# 1.17 23-Dec-2009 jacekm

Implementation of RFC 2920 PIPELINING extension, client side only for now.

This restructures the client_* API internals significantly. The code becomes
pipelining in nature. All SMTP commands are put on the output queue and
dequeued as quickly as possible. Once dequeued, they're moved to the receive
queue so that replies can be matched with previous commands.

Dequeuing commands from the output queue halts when the count of commands
currently in-pipeline (``cmdi'') is equal to the command send window (``cmdw'').
There are three cmdw values useful in practice:

0 clear pipeline, ie. inhibit all future sends
1 disable pipelining, ie. use old ``one-request-one-reply`` mode
SIZE_T_MAX enable pipelining, ie. dequeue as many commands as possible

At the beginning of session cmdw is 1. When it is found that peer supports
PIPELINING, it grows to SIZE_T_MAX. After dequeing DATA it is again 1. After
sending QUIT it is 0.

Each command dequeued from the output queue becomes a buf in a msgbuf. The act
of combining multiple commands into a single send operation did not need to be
implemented: buf_write() already combines bufs using iovec and sends them at
once using sendmsg(2).

Tested by todd@ and oga@

"looks good" to gilles@


# 1.16 14-Dec-2009 jacekm

Handle 6yz code as permanent error.


# 1.15 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.14 12-Dec-2009 jacekm

When acting as a client do content reads from the disk progressively
as the remote accepts more data instead of doing one big read into
the memory in the beginning of session.


# 1.13 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.12 11-Nov-2009 chl

add missing headers needed by time()

ok jacekm@


# 1.11 05-Nov-2009 jsing

Include a Date: header in bounce messages.

ok jacekm@ gilles@


# 1.10 05-Nov-2009 jsing

Introduce a 6yz status code, used internally to report permanent errors.
The 1yz and 6yz status codes are now removed prior to reporting the status
message in bounce messages, which provides an easy way to distinguish
between local and remote status messages. Initial diff from jacekm@

ok gilles@ jacekm@


# 1.9 16-Sep-2009 jacekm

Free resources when bounce enqueue fails due to a timeout.


# 1.8 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.7 04-Sep-2009 jacekm

Fix scheduling of bounces that could not be delivered.
ok gilles@


# 1.6 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.5 06-Aug-2009 gilles

when writing a bounce, follow the same rule as for mta sessions and prepend
with a dot lines starting with a dot


# 1.4 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.3 06-Aug-2009 gilles

fix a typo in bounce message t -> to


# 1.2 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.1 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.82 24-Apr-2020 eric

strip trailing CRs at smtp level rather than io level

ok millert@


# 1.81 25-Nov-2019 eric

use crlf line-ending during the internal smtp session

ok gilles@ martijn@


Revision tags: OPENBSD_6_5_BASE OPENBSD_6_6_BASE
# 1.80 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


Revision tags: OPENBSD_6_4_BASE
# 1.79 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.78 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


Revision tags: OPENBSD_6_1_BASE OPENBSD_6_2_BASE OPENBSD_6_3_BASE
# 1.77 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.76 22-Nov-2016 eric

Normalize the io input buffer internally when reinstalling the io event, so
the caller doesn't have to bother with this.

ok gilles@ sunil@


# 1.75 21-Nov-2016 eric

replace calls to iobuf_*() functions with the corresponding io_*() wrappers.

ok sunil@ gilles@


# 1.74 20-Nov-2016 eric

add dedicated functions to set fd and callback on a struct io.
simplify io_init() prototype.

ok sunil@ gilles@


# 1.73 16-Nov-2016 eric

pass the user pointer as parameter to the io callback instead of having
the user dereference the io structure.

ok millert@ gilles@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.72 03-Feb-2016 sunil

Use "esc_class" to classify bounce type instead of "errorline" as
we no longer prepend status code to "errorline". Fixes mismatch
between DSN's subject line and its content.

Ok jung@ gilles@ millert@


# 1.71 24-Dec-2015 mmcc

more e-mail -> email


# 1.70 14-Dec-2015 sunil

Fix bad indents and whitespaces.

Ok jung@ gilles@


# 1.69 14-Dec-2015 jung

remove trailing whitespace

ok sunil gilles


# 1.68 23-Nov-2015 sunil

Restructure bounce content as a multi-part MIME message.
Content-Type header diff from Philipp Takacs <philipp<at>bureaucracy.de>

Ok gilles@ jung@


# 1.67 07-Oct-2015 millert

Use getline(3) rather than fgetln(3). OK gilles@


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.66 20-Jan-2015 deraadt

use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


Revision tags: OPENBSD_5_6_BASE
# 1.65 28-May-2014 daniel

remove an errant semicolon.

ok gilles@


# 1.64 19-Apr-2014 gilles

(void) cast snprintf() calls that cannot truncate


# 1.63 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


Revision tags: OPENBSD_5_5_BASE
# 1.62 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.61 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.60 03-Dec-2013 eric

warn when failing to enqueue an internal bounce.


# 1.59 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.58 26-Oct-2013 eric

%i -> %d in format strings


Revision tags: OPENBSD_5_4_BASE
# 1.57 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.56 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.55 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


Revision tags: OPENBSD_5_3_BASE
# 1.54 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.53 23-Nov-2012 eric

knf

ok gilles@


# 1.52 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.51 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.50 03-Oct-2012 chl

don't try to cope with iobuf_init() failure, make it fatal() instead.

from eric@ input

ok gilles@


# 1.49 02-Oct-2012 chl

check iobuf_init() return value.

ok gilles@ eric@


# 1.48 26-Sep-2012 chl

fix memory leak in case of fdopen() failure

ok eric@ gilles@


# 1.47 18-Aug-2012 eric

Limit the number of bounce sessions running at the same time. When
committed, a bounce is put on a runnable list of bounces. This list
is drained to enqueue as much bounces as possible within the limit.

This avoids DoS'ing the server when lots of bounces are enqueued at
startup.

While there, allow new envelopes to be added to a bounce until the
the very last moment (i.e. when the list of recipients is written).

ok gilles@ chl@


# 1.46 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.45 09-Aug-2012 eric

remove unused function and prototypes


# 1.44 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.43 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.42 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.41 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


Revision tags: OPENBSD_5_1_BASE
# 1.40 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.39 12-Jan-2012 eric

The status field in the envelope is confusing. Its only purpose is to
notify the runner of what happened with an envelope that has been
scheduled. It is not part of the state of the envelope, and it is not
even dumped. So it should only be set by mta/mda, checked by runner
to decide what to do with the envelope, and ignored everywhere else.

ok gilles@


# 1.38 11-Jan-2012 eric

Finally remove the queue_message_update() function which ended up
being only called by bounce sessions, so most of the code there was
actually useless. The envelope is directly deleted or updated at the
relevant place.

ok gilles@


# 1.37 27-Dec-2011 eric

Instead of using a separate "bounce" queue, create the bounce envelope
directly as an envelope of the bounced message, just like "regular"
envelopes.

ok gilles@


# 1.36 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.35 27-Oct-2011 chl

Use PRI{x,d}64 in format strings instead of %llx, %lld or %qd to print {u_,}int64_t or time_t

While there, cast some time_t to int64_t

These will fix build warnings for portable smptd

ok gilles@ eric@


# 1.34 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.33 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


Revision tags: OPENBSD_5_0_BASE
# 1.32 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.31 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.30 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.29 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.28 14-Apr-2011 gilles

fsqueue now provides fsqueue_message_fd_r() and fsqueue_message_fd_rw() to
obtain a read{-only,/write} descriptor to the message file.

make sure smtpd uses the new API everywhere it needs a fd, and kill the
many functions that were used until now.


# 1.27 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.26 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.25 21-Mar-2011 gilles

do not close msgfd in bounce_session(), it is closed by client_close()


Revision tags: OPENBSD_4_9_BASE
# 1.24 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.23 09-Oct-2010 gilles

missing from previous commit


# 1.22 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.21 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.20 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.19 19-May-2010 gilles

cleanup-only commit, removes unrequired includes, no functionnal change


# 1.18 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


Revision tags: OPENBSD_4_7_BASE
# 1.17 23-Dec-2009 jacekm

Implementation of RFC 2920 PIPELINING extension, client side only for now.

This restructures the client_* API internals significantly. The code becomes
pipelining in nature. All SMTP commands are put on the output queue and
dequeued as quickly as possible. Once dequeued, they're moved to the receive
queue so that replies can be matched with previous commands.

Dequeuing commands from the output queue halts when the count of commands
currently in-pipeline (``cmdi'') is equal to the command send window (``cmdw'').
There are three cmdw values useful in practice:

0 clear pipeline, ie. inhibit all future sends
1 disable pipelining, ie. use old ``one-request-one-reply`` mode
SIZE_T_MAX enable pipelining, ie. dequeue as many commands as possible

At the beginning of session cmdw is 1. When it is found that peer supports
PIPELINING, it grows to SIZE_T_MAX. After dequeing DATA it is again 1. After
sending QUIT it is 0.

Each command dequeued from the output queue becomes a buf in a msgbuf. The act
of combining multiple commands into a single send operation did not need to be
implemented: buf_write() already combines bufs using iovec and sends them at
once using sendmsg(2).

Tested by todd@ and oga@

"looks good" to gilles@


# 1.16 14-Dec-2009 jacekm

Handle 6yz code as permanent error.


# 1.15 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.14 12-Dec-2009 jacekm

When acting as a client do content reads from the disk progressively
as the remote accepts more data instead of doing one big read into
the memory in the beginning of session.


# 1.13 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.12 11-Nov-2009 chl

add missing headers needed by time()

ok jacekm@


# 1.11 05-Nov-2009 jsing

Include a Date: header in bounce messages.

ok jacekm@ gilles@


# 1.10 05-Nov-2009 jsing

Introduce a 6yz status code, used internally to report permanent errors.
The 1yz and 6yz status codes are now removed prior to reporting the status
message in bounce messages, which provides an easy way to distinguish
between local and remote status messages. Initial diff from jacekm@

ok gilles@ jacekm@


# 1.9 16-Sep-2009 jacekm

Free resources when bounce enqueue fails due to a timeout.


# 1.8 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.7 04-Sep-2009 jacekm

Fix scheduling of bounces that could not be delivered.
ok gilles@


# 1.6 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.5 06-Aug-2009 gilles

when writing a bounce, follow the same rule as for mta sessions and prepend
with a dot lines starting with a dot


# 1.4 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.3 06-Aug-2009 gilles

fix a typo in bounce message t -> to


# 1.2 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.1 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.81 25-Nov-2019 eric

use crlf line-ending during the internal smtp session

ok gilles@ martijn@


Revision tags: OPENBSD_6_5_BASE OPENBSD_6_6_BASE
# 1.80 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


Revision tags: OPENBSD_6_4_BASE
# 1.79 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.78 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


Revision tags: OPENBSD_6_1_BASE OPENBSD_6_2_BASE OPENBSD_6_3_BASE
# 1.77 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.76 22-Nov-2016 eric

Normalize the io input buffer internally when reinstalling the io event, so
the caller doesn't have to bother with this.

ok gilles@ sunil@


# 1.75 21-Nov-2016 eric

replace calls to iobuf_*() functions with the corresponding io_*() wrappers.

ok sunil@ gilles@


# 1.74 20-Nov-2016 eric

add dedicated functions to set fd and callback on a struct io.
simplify io_init() prototype.

ok sunil@ gilles@


# 1.73 16-Nov-2016 eric

pass the user pointer as parameter to the io callback instead of having
the user dereference the io structure.

ok millert@ gilles@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.72 03-Feb-2016 sunil

Use "esc_class" to classify bounce type instead of "errorline" as
we no longer prepend status code to "errorline". Fixes mismatch
between DSN's subject line and its content.

Ok jung@ gilles@ millert@


# 1.71 24-Dec-2015 mmcc

more e-mail -> email


# 1.70 14-Dec-2015 sunil

Fix bad indents and whitespaces.

Ok jung@ gilles@


# 1.69 14-Dec-2015 jung

remove trailing whitespace

ok sunil gilles


# 1.68 23-Nov-2015 sunil

Restructure bounce content as a multi-part MIME message.
Content-Type header diff from Philipp Takacs <philipp<at>bureaucracy.de>

Ok gilles@ jung@


# 1.67 07-Oct-2015 millert

Use getline(3) rather than fgetln(3). OK gilles@


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.66 20-Jan-2015 deraadt

use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


Revision tags: OPENBSD_5_6_BASE
# 1.65 28-May-2014 daniel

remove an errant semicolon.

ok gilles@


# 1.64 19-Apr-2014 gilles

(void) cast snprintf() calls that cannot truncate


# 1.63 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


Revision tags: OPENBSD_5_5_BASE
# 1.62 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.61 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.60 03-Dec-2013 eric

warn when failing to enqueue an internal bounce.


# 1.59 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.58 26-Oct-2013 eric

%i -> %d in format strings


Revision tags: OPENBSD_5_4_BASE
# 1.57 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.56 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.55 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


Revision tags: OPENBSD_5_3_BASE
# 1.54 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.53 23-Nov-2012 eric

knf

ok gilles@


# 1.52 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.51 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.50 03-Oct-2012 chl

don't try to cope with iobuf_init() failure, make it fatal() instead.

from eric@ input

ok gilles@


# 1.49 02-Oct-2012 chl

check iobuf_init() return value.

ok gilles@ eric@


# 1.48 26-Sep-2012 chl

fix memory leak in case of fdopen() failure

ok eric@ gilles@


# 1.47 18-Aug-2012 eric

Limit the number of bounce sessions running at the same time. When
committed, a bounce is put on a runnable list of bounces. This list
is drained to enqueue as much bounces as possible within the limit.

This avoids DoS'ing the server when lots of bounces are enqueued at
startup.

While there, allow new envelopes to be added to a bounce until the
the very last moment (i.e. when the list of recipients is written).

ok gilles@ chl@


# 1.46 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.45 09-Aug-2012 eric

remove unused function and prototypes


# 1.44 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.43 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.42 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.41 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


Revision tags: OPENBSD_5_1_BASE
# 1.40 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.39 12-Jan-2012 eric

The status field in the envelope is confusing. Its only purpose is to
notify the runner of what happened with an envelope that has been
scheduled. It is not part of the state of the envelope, and it is not
even dumped. So it should only be set by mta/mda, checked by runner
to decide what to do with the envelope, and ignored everywhere else.

ok gilles@


# 1.38 11-Jan-2012 eric

Finally remove the queue_message_update() function which ended up
being only called by bounce sessions, so most of the code there was
actually useless. The envelope is directly deleted or updated at the
relevant place.

ok gilles@


# 1.37 27-Dec-2011 eric

Instead of using a separate "bounce" queue, create the bounce envelope
directly as an envelope of the bounced message, just like "regular"
envelopes.

ok gilles@


# 1.36 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.35 27-Oct-2011 chl

Use PRI{x,d}64 in format strings instead of %llx, %lld or %qd to print {u_,}int64_t or time_t

While there, cast some time_t to int64_t

These will fix build warnings for portable smptd

ok gilles@ eric@


# 1.34 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.33 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


Revision tags: OPENBSD_5_0_BASE
# 1.32 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.31 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.30 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.29 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.28 14-Apr-2011 gilles

fsqueue now provides fsqueue_message_fd_r() and fsqueue_message_fd_rw() to
obtain a read{-only,/write} descriptor to the message file.

make sure smtpd uses the new API everywhere it needs a fd, and kill the
many functions that were used until now.


# 1.27 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.26 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.25 21-Mar-2011 gilles

do not close msgfd in bounce_session(), it is closed by client_close()


Revision tags: OPENBSD_4_9_BASE
# 1.24 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.23 09-Oct-2010 gilles

missing from previous commit


# 1.22 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.21 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.20 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.19 19-May-2010 gilles

cleanup-only commit, removes unrequired includes, no functionnal change


# 1.18 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


Revision tags: OPENBSD_4_7_BASE
# 1.17 23-Dec-2009 jacekm

Implementation of RFC 2920 PIPELINING extension, client side only for now.

This restructures the client_* API internals significantly. The code becomes
pipelining in nature. All SMTP commands are put on the output queue and
dequeued as quickly as possible. Once dequeued, they're moved to the receive
queue so that replies can be matched with previous commands.

Dequeuing commands from the output queue halts when the count of commands
currently in-pipeline (``cmdi'') is equal to the command send window (``cmdw'').
There are three cmdw values useful in practice:

0 clear pipeline, ie. inhibit all future sends
1 disable pipelining, ie. use old ``one-request-one-reply`` mode
SIZE_T_MAX enable pipelining, ie. dequeue as many commands as possible

At the beginning of session cmdw is 1. When it is found that peer supports
PIPELINING, it grows to SIZE_T_MAX. After dequeing DATA it is again 1. After
sending QUIT it is 0.

Each command dequeued from the output queue becomes a buf in a msgbuf. The act
of combining multiple commands into a single send operation did not need to be
implemented: buf_write() already combines bufs using iovec and sends them at
once using sendmsg(2).

Tested by todd@ and oga@

"looks good" to gilles@


# 1.16 14-Dec-2009 jacekm

Handle 6yz code as permanent error.


# 1.15 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.14 12-Dec-2009 jacekm

When acting as a client do content reads from the disk progressively
as the remote accepts more data instead of doing one big read into
the memory in the beginning of session.


# 1.13 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.12 11-Nov-2009 chl

add missing headers needed by time()

ok jacekm@


# 1.11 05-Nov-2009 jsing

Include a Date: header in bounce messages.

ok jacekm@ gilles@


# 1.10 05-Nov-2009 jsing

Introduce a 6yz status code, used internally to report permanent errors.
The 1yz and 6yz status codes are now removed prior to reporting the status
message in bounce messages, which provides an easy way to distinguish
between local and remote status messages. Initial diff from jacekm@

ok gilles@ jacekm@


# 1.9 16-Sep-2009 jacekm

Free resources when bounce enqueue fails due to a timeout.


# 1.8 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.7 04-Sep-2009 jacekm

Fix scheduling of bounces that could not be delivered.
ok gilles@


# 1.6 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.5 06-Aug-2009 gilles

when writing a bounce, follow the same rule as for mta sessions and prepend
with a dot lines starting with a dot


# 1.4 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.3 06-Aug-2009 gilles

fix a typo in bounce message t -> to


# 1.2 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.1 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.80 08-Dec-2018 sunil

Use correct RFC 3464 specified values for Action field in a DSN.
error -> failed
success -> delivered

This fixes DSN parsing for Mailman. Issue reported by Cristiano
Costa on misc@opensmtpd.org.

While here, rename enums to reflect the intent and properly handle
envelope ascii load/dump to understand change in the values.

Suggestions and ok gilles@


Revision tags: OPENBSD_6_4_BASE
# 1.79 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.78 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


Revision tags: OPENBSD_6_1_BASE OPENBSD_6_2_BASE OPENBSD_6_3_BASE
# 1.77 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.76 22-Nov-2016 eric

Normalize the io input buffer internally when reinstalling the io event, so
the caller doesn't have to bother with this.

ok gilles@ sunil@


# 1.75 21-Nov-2016 eric

replace calls to iobuf_*() functions with the corresponding io_*() wrappers.

ok sunil@ gilles@


# 1.74 20-Nov-2016 eric

add dedicated functions to set fd and callback on a struct io.
simplify io_init() prototype.

ok sunil@ gilles@


# 1.73 16-Nov-2016 eric

pass the user pointer as parameter to the io callback instead of having
the user dereference the io structure.

ok millert@ gilles@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.72 03-Feb-2016 sunil

Use "esc_class" to classify bounce type instead of "errorline" as
we no longer prepend status code to "errorline". Fixes mismatch
between DSN's subject line and its content.

Ok jung@ gilles@ millert@


# 1.71 24-Dec-2015 mmcc

more e-mail -> email


# 1.70 14-Dec-2015 sunil

Fix bad indents and whitespaces.

Ok jung@ gilles@


# 1.69 14-Dec-2015 jung

remove trailing whitespace

ok sunil gilles


# 1.68 23-Nov-2015 sunil

Restructure bounce content as a multi-part MIME message.
Content-Type header diff from Philipp Takacs <philipp<at>bureaucracy.de>

Ok gilles@ jung@


# 1.67 07-Oct-2015 millert

Use getline(3) rather than fgetln(3). OK gilles@


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.66 20-Jan-2015 deraadt

use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


Revision tags: OPENBSD_5_6_BASE
# 1.65 28-May-2014 daniel

remove an errant semicolon.

ok gilles@


# 1.64 19-Apr-2014 gilles

(void) cast snprintf() calls that cannot truncate


# 1.63 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


Revision tags: OPENBSD_5_5_BASE
# 1.62 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.61 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.60 03-Dec-2013 eric

warn when failing to enqueue an internal bounce.


# 1.59 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.58 26-Oct-2013 eric

%i -> %d in format strings


Revision tags: OPENBSD_5_4_BASE
# 1.57 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.56 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.55 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


Revision tags: OPENBSD_5_3_BASE
# 1.54 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.53 23-Nov-2012 eric

knf

ok gilles@


# 1.52 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.51 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.50 03-Oct-2012 chl

don't try to cope with iobuf_init() failure, make it fatal() instead.

from eric@ input

ok gilles@


# 1.49 02-Oct-2012 chl

check iobuf_init() return value.

ok gilles@ eric@


# 1.48 26-Sep-2012 chl

fix memory leak in case of fdopen() failure

ok eric@ gilles@


# 1.47 18-Aug-2012 eric

Limit the number of bounce sessions running at the same time. When
committed, a bounce is put on a runnable list of bounces. This list
is drained to enqueue as much bounces as possible within the limit.

This avoids DoS'ing the server when lots of bounces are enqueued at
startup.

While there, allow new envelopes to be added to a bounce until the
the very last moment (i.e. when the list of recipients is written).

ok gilles@ chl@


# 1.46 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.45 09-Aug-2012 eric

remove unused function and prototypes


# 1.44 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.43 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.42 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.41 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


Revision tags: OPENBSD_5_1_BASE
# 1.40 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.39 12-Jan-2012 eric

The status field in the envelope is confusing. Its only purpose is to
notify the runner of what happened with an envelope that has been
scheduled. It is not part of the state of the envelope, and it is not
even dumped. So it should only be set by mta/mda, checked by runner
to decide what to do with the envelope, and ignored everywhere else.

ok gilles@


# 1.38 11-Jan-2012 eric

Finally remove the queue_message_update() function which ended up
being only called by bounce sessions, so most of the code there was
actually useless. The envelope is directly deleted or updated at the
relevant place.

ok gilles@


# 1.37 27-Dec-2011 eric

Instead of using a separate "bounce" queue, create the bounce envelope
directly as an envelope of the bounced message, just like "regular"
envelopes.

ok gilles@


# 1.36 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.35 27-Oct-2011 chl

Use PRI{x,d}64 in format strings instead of %llx, %lld or %qd to print {u_,}int64_t or time_t

While there, cast some time_t to int64_t

These will fix build warnings for portable smptd

ok gilles@ eric@


# 1.34 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.33 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


Revision tags: OPENBSD_5_0_BASE
# 1.32 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.31 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.30 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.29 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.28 14-Apr-2011 gilles

fsqueue now provides fsqueue_message_fd_r() and fsqueue_message_fd_rw() to
obtain a read{-only,/write} descriptor to the message file.

make sure smtpd uses the new API everywhere it needs a fd, and kill the
many functions that were used until now.


# 1.27 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.26 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.25 21-Mar-2011 gilles

do not close msgfd in bounce_session(), it is closed by client_close()


Revision tags: OPENBSD_4_9_BASE
# 1.24 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.23 09-Oct-2010 gilles

missing from previous commit


# 1.22 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.21 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.20 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.19 19-May-2010 gilles

cleanup-only commit, removes unrequired includes, no functionnal change


# 1.18 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


Revision tags: OPENBSD_4_7_BASE
# 1.17 23-Dec-2009 jacekm

Implementation of RFC 2920 PIPELINING extension, client side only for now.

This restructures the client_* API internals significantly. The code becomes
pipelining in nature. All SMTP commands are put on the output queue and
dequeued as quickly as possible. Once dequeued, they're moved to the receive
queue so that replies can be matched with previous commands.

Dequeuing commands from the output queue halts when the count of commands
currently in-pipeline (``cmdi'') is equal to the command send window (``cmdw'').
There are three cmdw values useful in practice:

0 clear pipeline, ie. inhibit all future sends
1 disable pipelining, ie. use old ``one-request-one-reply`` mode
SIZE_T_MAX enable pipelining, ie. dequeue as many commands as possible

At the beginning of session cmdw is 1. When it is found that peer supports
PIPELINING, it grows to SIZE_T_MAX. After dequeing DATA it is again 1. After
sending QUIT it is 0.

Each command dequeued from the output queue becomes a buf in a msgbuf. The act
of combining multiple commands into a single send operation did not need to be
implemented: buf_write() already combines bufs using iovec and sends them at
once using sendmsg(2).

Tested by todd@ and oga@

"looks good" to gilles@


# 1.16 14-Dec-2009 jacekm

Handle 6yz code as permanent error.


# 1.15 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.14 12-Dec-2009 jacekm

When acting as a client do content reads from the disk progressively
as the remote accepts more data instead of doing one big read into
the memory in the beginning of session.


# 1.13 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.12 11-Nov-2009 chl

add missing headers needed by time()

ok jacekm@


# 1.11 05-Nov-2009 jsing

Include a Date: header in bounce messages.

ok jacekm@ gilles@


# 1.10 05-Nov-2009 jsing

Introduce a 6yz status code, used internally to report permanent errors.
The 1yz and 6yz status codes are now removed prior to reporting the status
message in bounce messages, which provides an easy way to distinguish
between local and remote status messages. Initial diff from jacekm@

ok gilles@ jacekm@


# 1.9 16-Sep-2009 jacekm

Free resources when bounce enqueue fails due to a timeout.


# 1.8 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.7 04-Sep-2009 jacekm

Fix scheduling of bounces that could not be delivered.
ok gilles@


# 1.6 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.5 06-Aug-2009 gilles

when writing a bounce, follow the same rule as for mta sessions and prepend
with a dot lines starting with a dot


# 1.4 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.3 06-Aug-2009 gilles

fix a typo in bounce message t -> to


# 1.2 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.1 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


# 1.79 31-May-2018 gilles

remove 'where' parameter from all x*() functions in utils.c, it doesn't
really help us with anything, propagate the change in codebase

ok millert@


# 1.78 24-May-2018 gilles

switch smtpd to new grammar

ok eric@


Revision tags: OPENBSD_6_1_BASE OPENBSD_6_2_BASE OPENBSD_6_3_BASE
# 1.77 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.76 22-Nov-2016 eric

Normalize the io input buffer internally when reinstalling the io event, so
the caller doesn't have to bother with this.

ok gilles@ sunil@


# 1.75 21-Nov-2016 eric

replace calls to iobuf_*() functions with the corresponding io_*() wrappers.

ok sunil@ gilles@


# 1.74 20-Nov-2016 eric

add dedicated functions to set fd and callback on a struct io.
simplify io_init() prototype.

ok sunil@ gilles@


# 1.73 16-Nov-2016 eric

pass the user pointer as parameter to the io callback instead of having
the user dereference the io structure.

ok millert@ gilles@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.72 03-Feb-2016 sunil

Use "esc_class" to classify bounce type instead of "errorline" as
we no longer prepend status code to "errorline". Fixes mismatch
between DSN's subject line and its content.

Ok jung@ gilles@ millert@


# 1.71 24-Dec-2015 mmcc

more e-mail -> email


# 1.70 14-Dec-2015 sunil

Fix bad indents and whitespaces.

Ok jung@ gilles@


# 1.69 14-Dec-2015 jung

remove trailing whitespace

ok sunil gilles


# 1.68 23-Nov-2015 sunil

Restructure bounce content as a multi-part MIME message.
Content-Type header diff from Philipp Takacs <philipp<at>bureaucracy.de>

Ok gilles@ jung@


# 1.67 07-Oct-2015 millert

Use getline(3) rather than fgetln(3). OK gilles@


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.66 20-Jan-2015 deraadt

use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


Revision tags: OPENBSD_5_6_BASE
# 1.65 28-May-2014 daniel

remove an errant semicolon.

ok gilles@


# 1.64 19-Apr-2014 gilles

(void) cast snprintf() calls that cannot truncate


# 1.63 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


Revision tags: OPENBSD_5_5_BASE
# 1.62 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.61 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.60 03-Dec-2013 eric

warn when failing to enqueue an internal bounce.


# 1.59 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.58 26-Oct-2013 eric

%i -> %d in format strings


Revision tags: OPENBSD_5_4_BASE
# 1.57 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.56 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.55 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


Revision tags: OPENBSD_5_3_BASE
# 1.54 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.53 23-Nov-2012 eric

knf

ok gilles@


# 1.52 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.51 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.50 03-Oct-2012 chl

don't try to cope with iobuf_init() failure, make it fatal() instead.

from eric@ input

ok gilles@


# 1.49 02-Oct-2012 chl

check iobuf_init() return value.

ok gilles@ eric@


# 1.48 26-Sep-2012 chl

fix memory leak in case of fdopen() failure

ok eric@ gilles@


# 1.47 18-Aug-2012 eric

Limit the number of bounce sessions running at the same time. When
committed, a bounce is put on a runnable list of bounces. This list
is drained to enqueue as much bounces as possible within the limit.

This avoids DoS'ing the server when lots of bounces are enqueued at
startup.

While there, allow new envelopes to be added to a bounce until the
the very last moment (i.e. when the list of recipients is written).

ok gilles@ chl@


# 1.46 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.45 09-Aug-2012 eric

remove unused function and prototypes


# 1.44 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.43 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.42 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.41 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


Revision tags: OPENBSD_5_1_BASE
# 1.40 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.39 12-Jan-2012 eric

The status field in the envelope is confusing. Its only purpose is to
notify the runner of what happened with an envelope that has been
scheduled. It is not part of the state of the envelope, and it is not
even dumped. So it should only be set by mta/mda, checked by runner
to decide what to do with the envelope, and ignored everywhere else.

ok gilles@


# 1.38 11-Jan-2012 eric

Finally remove the queue_message_update() function which ended up
being only called by bounce sessions, so most of the code there was
actually useless. The envelope is directly deleted or updated at the
relevant place.

ok gilles@


# 1.37 27-Dec-2011 eric

Instead of using a separate "bounce" queue, create the bounce envelope
directly as an envelope of the bounced message, just like "regular"
envelopes.

ok gilles@


# 1.36 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.35 27-Oct-2011 chl

Use PRI{x,d}64 in format strings instead of %llx, %lld or %qd to print {u_,}int64_t or time_t

While there, cast some time_t to int64_t

These will fix build warnings for portable smptd

ok gilles@ eric@


# 1.34 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.33 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


Revision tags: OPENBSD_5_0_BASE
# 1.32 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.31 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.30 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.29 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.28 14-Apr-2011 gilles

fsqueue now provides fsqueue_message_fd_r() and fsqueue_message_fd_rw() to
obtain a read{-only,/write} descriptor to the message file.

make sure smtpd uses the new API everywhere it needs a fd, and kill the
many functions that were used until now.


# 1.27 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.26 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.25 21-Mar-2011 gilles

do not close msgfd in bounce_session(), it is closed by client_close()


Revision tags: OPENBSD_4_9_BASE
# 1.24 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.23 09-Oct-2010 gilles

missing from previous commit


# 1.22 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.21 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.20 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.19 19-May-2010 gilles

cleanup-only commit, removes unrequired includes, no functionnal change


# 1.18 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


Revision tags: OPENBSD_4_7_BASE
# 1.17 23-Dec-2009 jacekm

Implementation of RFC 2920 PIPELINING extension, client side only for now.

This restructures the client_* API internals significantly. The code becomes
pipelining in nature. All SMTP commands are put on the output queue and
dequeued as quickly as possible. Once dequeued, they're moved to the receive
queue so that replies can be matched with previous commands.

Dequeuing commands from the output queue halts when the count of commands
currently in-pipeline (``cmdi'') is equal to the command send window (``cmdw'').
There are three cmdw values useful in practice:

0 clear pipeline, ie. inhibit all future sends
1 disable pipelining, ie. use old ``one-request-one-reply`` mode
SIZE_T_MAX enable pipelining, ie. dequeue as many commands as possible

At the beginning of session cmdw is 1. When it is found that peer supports
PIPELINING, it grows to SIZE_T_MAX. After dequeing DATA it is again 1. After
sending QUIT it is 0.

Each command dequeued from the output queue becomes a buf in a msgbuf. The act
of combining multiple commands into a single send operation did not need to be
implemented: buf_write() already combines bufs using iovec and sends them at
once using sendmsg(2).

Tested by todd@ and oga@

"looks good" to gilles@


# 1.16 14-Dec-2009 jacekm

Handle 6yz code as permanent error.


# 1.15 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.14 12-Dec-2009 jacekm

When acting as a client do content reads from the disk progressively
as the remote accepts more data instead of doing one big read into
the memory in the beginning of session.


# 1.13 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.12 11-Nov-2009 chl

add missing headers needed by time()

ok jacekm@


# 1.11 05-Nov-2009 jsing

Include a Date: header in bounce messages.

ok jacekm@ gilles@


# 1.10 05-Nov-2009 jsing

Introduce a 6yz status code, used internally to report permanent errors.
The 1yz and 6yz status codes are now removed prior to reporting the status
message in bounce messages, which provides an easy way to distinguish
between local and remote status messages. Initial diff from jacekm@

ok gilles@ jacekm@


# 1.9 16-Sep-2009 jacekm

Free resources when bounce enqueue fails due to a timeout.


# 1.8 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.7 04-Sep-2009 jacekm

Fix scheduling of bounces that could not be delivered.
ok gilles@


# 1.6 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.5 06-Aug-2009 gilles

when writing a bounce, follow the same rule as for mta sessions and prepend
with a dot lines starting with a dot


# 1.4 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.3 06-Aug-2009 gilles

fix a typo in bounce message t -> to


# 1.2 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.1 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@


Revision tags: OPENBSD_6_1_BASE OPENBSD_6_2_BASE
# 1.77 30-Nov-2016 eric

make struct io opaque:

- move struct io definition to ioev.c
- replace io_init/io_clear with io_new/io_free
- allocate an iobuf for each new io internally
- use struct io pointer in the rest of the code
- remove remaining uses of iobuf_*

ok gilles@ sunil@


# 1.76 22-Nov-2016 eric

Normalize the io input buffer internally when reinstalling the io event, so
the caller doesn't have to bother with this.

ok gilles@ sunil@


# 1.75 21-Nov-2016 eric

replace calls to iobuf_*() functions with the corresponding io_*() wrappers.

ok sunil@ gilles@


# 1.74 20-Nov-2016 eric

add dedicated functions to set fd and callback on a struct io.
simplify io_init() prototype.

ok sunil@ gilles@


# 1.73 16-Nov-2016 eric

pass the user pointer as parameter to the io callback instead of having
the user dereference the io structure.

ok millert@ gilles@


Revision tags: OPENBSD_5_9_BASE OPENBSD_6_0_BASE
# 1.72 03-Feb-2016 sunil

Use "esc_class" to classify bounce type instead of "errorline" as
we no longer prepend status code to "errorline". Fixes mismatch
between DSN's subject line and its content.

Ok jung@ gilles@ millert@


# 1.71 24-Dec-2015 mmcc

more e-mail -> email


# 1.70 14-Dec-2015 sunil

Fix bad indents and whitespaces.

Ok jung@ gilles@


# 1.69 14-Dec-2015 jung

remove trailing whitespace

ok sunil gilles


# 1.68 23-Nov-2015 sunil

Restructure bounce content as a multi-part MIME message.
Content-Type header diff from Philipp Takacs <philipp<at>bureaucracy.de>

Ok gilles@ jung@


# 1.67 07-Oct-2015 millert

Use getline(3) rather than fgetln(3). OK gilles@


Revision tags: OPENBSD_5_7_BASE OPENBSD_5_8_BASE
# 1.66 20-Jan-2015 deraadt

use <limits.h> comprehensively. For now try to push <> includes to
each .c file, and out of the .h files. To avoid overinclude.
ok gilles, in principle. If this has been done right, -portable should
become easier to maintain.


Revision tags: OPENBSD_5_6_BASE
# 1.65 28-May-2014 daniel

remove an errant semicolon.

ok gilles@


# 1.64 19-Apr-2014 gilles

(void) cast snprintf() calls that cannot truncate


# 1.63 04-Apr-2014 eric

Merge the mda, mta and smtp processes into a single unprivileged
process managing message reception, delivery and transfer. Mostly
mechanical, but very intrusive as it required to rewamp all IMSG to
fix ambiguities.

with and ok gilles@


Revision tags: OPENBSD_5_5_BASE
# 1.62 04-Feb-2014 eric

Add support for DSN and Enhanced Status Code


# 1.61 04-Feb-2014 eric

internal improvements and cleanups

- get rid of the whole penalty thing for failed envelopes in the mta and scheduler.
- do not disable routes on smtp errors
- try to schedule all types of envelopes on each scheduler frame.


# 1.60 03-Dec-2013 eric

warn when failing to enqueue an internal bounce.


# 1.59 06-Nov-2013 eric

Much much improved config parser and related changes.
Simplify code and do not impose an order on conditions and rule options.

Format changes that may require smtpd.conf update for some setups:

- SSL certificates are no longer automatically loaded, but must be
explicitely declared using the "pki" keyword.
- "certificate" option becomes "pki" in listener and accept rules.
- "ssl://" becomes "secure://" in relay via rules.
- "helo" becomes "hostnames" in relay rules

New features:

- accept rules do not need an explicit action, in which case alias table
or .forward must provide one.
- new "forward-only" action to force relaying and reject rcpts that expand
as local delivery.
- "!" (negation) modifier on rule matching conditions.
- new "recipient" rule matching condition.
- new "verify" option on listeners and relay rules to reject invalid
certificates.

Other changes:

- remember the helo name advertised on incoming mail and use it for sending
bounces.
- bump envelope version (existing envelopes are updated on-the-fly).


# 1.58 26-Oct-2013 eric

%i -> %d in format strings


Revision tags: OPENBSD_5_4_BASE
# 1.57 19-Jul-2013 eric

scheduler improvements:
- implement suspend/resume scheduling for individual envelopes or message,
with the associated smtpctl commands.
- allow the mta to request immediate scheduling of an envelope.
- on temporary failures a penalty can be given to further delay the next try.


# 1.56 24-May-2013 eric

sync with OpenSMTPD 5.3.2

ok gilles@


# 1.55 12-Apr-2013 eric

replace MAX_LINE_SIZE and SMTP_LINE_MAX with SMTPD_MAXLINESIZE for
consistency and clarity. Remove useless and confusing extra byte in
a few arrays based on this define.

ok gilles@


Revision tags: OPENBSD_5_3_BASE
# 1.54 26-Jan-2013 gilles

Sync with our smtpd repo:

* first bricks of ldap and sqlite support (not finished but both working)
* new table API to replace map API, all lookups are done through tables
* improved handling of temporary errors throughout the daemon
* improved scheduler and mta logic: connection reuse, optimizes batches
* improved queue: more tolerant to admin errors, new layout, less disk-IO
* improved memory usage under high load
* SSL certs/keys isolated to lookup process to avoid facing network
* VIRTUAL support improved, fully virtual setups possible now
* runtime tracing of processes through smtpctl trace
* ssl_privsep.c sync-ed with relayd
* ssl.c no longer contains smtpd specific interfaces
* smtpd-specific ssl bits moved to ssl_smtpd.c
* update mail address in copyright

FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE. FLUSH YOUR QUEUE.

smtpd.conf(5) simplified, it will require adaptations

ok eric@


# 1.53 23-Nov-2012 eric

knf

ok gilles@


# 1.52 12-Nov-2012 eric

Cleanups and improvements:

* Log more events (especially client session) and use a better scheme
for that: each messages is prefixed with a token to easily identify
its class:
- info/warn/debug: general server messages
- smtp-in: smtp client connections
- relay: status update for relayed messages
- delivery: status update for local deliveries

* Implement "smtpctl monitor" to display updates of selected internal
counters.

* When reloading the on-disk queue at startup do not commit a message
if no envelope was submitted for that message.

* Remove unused stuff in the config parser.

ok gilles@


# 1.51 07-Oct-2012 chl

convert iobuf_queue()'s to iobuf_fqueue(). (idea from gilles@)
introduce iobuf_xinit() and iobuf_xfqueue(). (idea from eric@)

ok gilles@


# 1.50 03-Oct-2012 chl

don't try to cope with iobuf_init() failure, make it fatal() instead.

from eric@ input

ok gilles@


# 1.49 02-Oct-2012 chl

check iobuf_init() return value.

ok gilles@ eric@


# 1.48 26-Sep-2012 chl

fix memory leak in case of fdopen() failure

ok eric@ gilles@


# 1.47 18-Aug-2012 eric

Limit the number of bounce sessions running at the same time. When
committed, a bounce is put on a runnable list of bounces. This list
is drained to enqueue as much bounces as possible within the limit.

This avoids DoS'ing the server when lots of bounces are enqueued at
startup.

While there, allow new envelopes to be added to a bounce until the
the very last moment (i.e. when the list of recipients is written).

ok gilles@ chl@


# 1.46 09-Aug-2012 eric

Allow failure reports for different recipients of the same message
to be grouped into a single bounce message.

The bounce structure keeps a list of envelopes. For now, the list
is constructed by delaying the re-enqueuing of a bounce envelope a
bit, to wait for other bounces from the same message to be part of
the same report.


# 1.45 09-Aug-2012 eric

remove unused function and prototypes


# 1.44 09-Aug-2012 eric

Improve the message flows to completely isolate operations on the
queue backend within the queue process.

The scheduler sends envelope ids to the queue process which loads
the envelope and forward the request to the agent responsible for
the delivery. The result is sent by the agent to the queue which
updates the storage before notifying the scheduler.

Bounces are created and enqueued (from the client side) by the
queue process, rather than the scheduler.

ok gilles@


# 1.43 08-Aug-2012 eric

Improve the scheduler backend API.

New envelopes are pushed into the scheduler through the insert()
commit() rollback() transactional interface functions.

Worklists are pulled from the scheduler through a single batch()
interface function, which returns a list of envelope ids and the
type of processing. Envelopes returned in this batch are said to
be "in-flight", as opposed to "pending". They are supposed to be
processed in some way, and either updated() or deleted() at some
point.

The schedule()/remove() functions are used to alter the internal
state of "pending" envelopes to make them schedulable. The enve-
lopes will be part of a worklist on the next call to batch().

Rewrite the scheduler_ramqueue backend.

The initial queue loading in now done by the queue.

ok gilles@


Revision tags: OPENBSD_5_2_BASE
# 1.42 09-Jul-2012 gilles

- runner is the terminology we used back when we had runqueues, we no
longer have them and runner is actually a scheduler so rename.
- introduce scheduler_backend which does the same to scheduler than
queue_backend does to queue and map_backend does to maps
- remove all occurences of RUNNER and runner, replace them with SCHEDULER
and scheduler

ok eric@, ok chl@


# 1.41 20-Jun-2012 eric

Finally get rid of the queue_kind enum in the queue API. Keep that
internally in fsqueue backend for now, and let the fsqueue_message()
and fsqueue_envelope() dispatchers do the right thing.

Based on a diff by chl@

ok chl@ gilles@


Revision tags: OPENBSD_5_1_BASE
# 1.40 29-Jan-2012 eric

Rewrite io code in smtp and mta using the iobuf/ioev interface to have
a better separation between io and protocol logic. As a side-effect,
it fixes a couple of long-standing issues in the io path, and
hopefully add fresh ones instead. Kill client.c in the process.

ok gilles@


# 1.39 12-Jan-2012 eric

The status field in the envelope is confusing. Its only purpose is to
notify the runner of what happened with an envelope that has been
scheduled. It is not part of the state of the envelope, and it is not
even dumped. So it should only be set by mta/mda, checked by runner
to decide what to do with the envelope, and ignored everywhere else.

ok gilles@


# 1.38 11-Jan-2012 eric

Finally remove the queue_message_update() function which ended up
being only called by bounce sessions, so most of the code there was
actually useless. The envelope is directly deleted or updated at the
relevant place.

ok gilles@


# 1.37 27-Dec-2011 eric

Instead of using a separate "bounce" queue, create the bounce envelope
directly as an envelope of the bounced message, just like "regular"
envelopes.

ok gilles@


# 1.36 14-Dec-2011 eric

finally kill queue_shared.c and move what is left to bounce.c
where it belongs.

ok gilles@


# 1.35 27-Oct-2011 chl

Use PRI{x,d}64 in format strings instead of %llx, %lld or %qd to print {u_,}int64_t or time_t

While there, cast some time_t to int64_t

These will fix build warnings for portable smptd

ok gilles@ eric@


# 1.34 23-Oct-2011 gilles

fsqueue no longer stores envelopes by dumping the structure, instead use a
couple of load/dump functions to convert to and from a human readable fmt.
while at it kill struct delivery and merge back its fields to the envelope.

this basically means we shouldn't require users to flush their queues every
time we make a change to struct envelope.

work is not done, but we're at a better state than the binary fsqueue so
we'll improve it in-tree.

has been running on my own box for the last 12 hours or so
ok eric@, chl@


# 1.33 01-Sep-2011 eric

Introduce a small set of functions to manage stat counters in a
simpler and hopefully saner way.

ok gilles@ chl@


Revision tags: OPENBSD_5_0_BASE
# 1.32 16-May-2011 gilles

murder struct path and make sure smtpd uses simpler structures that do not
bring a shitload of unnecessary information everywhere. this required many
parts of smtpd to be refactored and more specifically envelope expansion.

in the process lots of code got simplified, and the envelope expansion code
has been isolated to lka_session.c with some longstanding bugs fixed.

Diff has been tested by many with no major regression reported.
armani@ spotted a bug in a setup where a domain is listed a both primary
and virtual, I will fix that in-tree as it's becoming painful to maintain
this diff out.


# 1.31 01-May-2011 eric

the smtpd env is meant to be global, so do not pass it all around.

discussed with and ok gilles@


# 1.30 17-Apr-2011 gilles

a structure describing an envelope should be called struct envelope, not
struct message ...


# 1.29 15-Apr-2011 gilles

kill message_id and message_uid

smtpd now has an evpid associated to each delivery message, the evpid is an
u_int64_t where the upper 32 bits are the msgid, and the 32 bits are the
envelope unique identifier for that message. this results in lots of space
saved in both disk-based and ram-based queues, but also simplifies a lot of
code.

change has been stressed on my desktop, and has ran on my MX for the entire
afternoon without a regression.


# 1.28 14-Apr-2011 gilles

fsqueue now provides fsqueue_message_fd_r() and fsqueue_message_fd_rw() to
obtain a read{-only,/write} descriptor to the message file.

make sure smtpd uses the new API everywhere it needs a fd, and kill the
many functions that were used until now.


# 1.27 14-Apr-2011 gilles

fsqueue queue backend will implement a filesystem queue:
- fsqueue->setup() performs the queue initialization;
- fsqueue->message() controls messages;
- fsqueue->envelope() controls envelopes;

This commit brings the following to fsbackend:
fsqueue_setup(), fsqueue_message_delete(), fsqueue_envelope_load(),
fsqueue_envelope_update(), fsqueue_envelope_delete().

It also makes smtpd use the queue_backend API for these operations.


# 1.26 26-Mar-2011 gilles

have the client API receive a stdio stream rather than a fd to the message
fd. this shifts responsibility for the fclose to the caller, prevents a
memory leak and makes everyone happy.

diff by Jared Yanovich, thanks !


# 1.25 21-Mar-2011 gilles

do not close msgfd in bounce_session(), it is closed by client_close()


Revision tags: OPENBSD_4_9_BASE
# 1.24 28-Nov-2010 gilles

a bit of .h cleanups, no functionnal change


# 1.23 09-Oct-2010 gilles

missing from previous commit


# 1.22 01-Jun-2010 jacekm

new queue, again; gcc2 compile tested by deraadt


# 1.21 01-Jun-2010 jacekm

New queue doesn't compile on gcc2, back out. Spotted by deraadt@


# 1.20 31-May-2010 jacekm

Rewrite entire queue code.

Major goals:

1) Fix bad performance caused by the runner process doing full queue
read in 1s intervals. My Soekris can now happily accept >50 msg/s
while having multi-thousand queue; before, one hundred queue would
bring the system to its knees.

2) Introduce Qmail-like scheduler that doesn't write as much to the
disk so that it needs less code for servicing error conditions,
which in some places can be tricky to get right.

3) Introduce separation between the scheduler and the backend; these
two queue aspects shouldn't be too tied too each other. This means
that eg. storing queue in SQL requires rewrite of just queue_backend.c.

4) Make on-disk queue format architecture independent, and more
easily extensible, to reduce number of flag days in the future.

Minor goals:

ENOSPC no longer prevents delivery attempts, fixed session limiting
for relayed mail, improved batching of "relay via" mails, human-readable
mailq output, "show queue raw" command, clearer logging, sending
of single bounce about multiple recipients, exact delay= computation,
zero delay between deliveries while within session limit (currently
1s delay between re-scheduling is enforced), mta no longer requests
content fd, corrected session limit for bounce submissions, tiny
<100B queue files instead of multi-KB, detect loops before accepting
mail, reduce traffic on imsg channels by killing enormous struct
submit_status.


# 1.19 19-May-2010 gilles

cleanup-only commit, removes unrequired includes, no functionnal change


# 1.18 22-Apr-2010 jacekm

Fix a case of runner trying to send imsg directly to smtp process instead
of forwarding it via queue.


Revision tags: OPENBSD_4_7_BASE
# 1.17 23-Dec-2009 jacekm

Implementation of RFC 2920 PIPELINING extension, client side only for now.

This restructures the client_* API internals significantly. The code becomes
pipelining in nature. All SMTP commands are put on the output queue and
dequeued as quickly as possible. Once dequeued, they're moved to the receive
queue so that replies can be matched with previous commands.

Dequeuing commands from the output queue halts when the count of commands
currently in-pipeline (``cmdi'') is equal to the command send window (``cmdw'').
There are three cmdw values useful in practice:

0 clear pipeline, ie. inhibit all future sends
1 disable pipelining, ie. use old ``one-request-one-reply`` mode
SIZE_T_MAX enable pipelining, ie. dequeue as many commands as possible

At the beginning of session cmdw is 1. When it is found that peer supports
PIPELINING, it grows to SIZE_T_MAX. After dequeing DATA it is again 1. After
sending QUIT it is 0.

Each command dequeued from the output queue becomes a buf in a msgbuf. The act
of combining multiple commands into a single send operation did not need to be
implemented: buf_write() already combines bufs using iovec and sends them at
once using sendmsg(2).

Tested by todd@ and oga@

"looks good" to gilles@


# 1.16 14-Dec-2009 jacekm

Handle 6yz code as permanent error.


# 1.15 14-Dec-2009 jacekm

Control maximum number of bounce sessions similarly to how the mta and mda
are now controlled.


# 1.14 12-Dec-2009 jacekm

When acting as a client do content reads from the disk progressively
as the remote accepts more data instead of doing one big read into
the memory in the beginning of session.


# 1.13 12-Dec-2009 jacekm

Simplify client_* api, mainly by making fatal conditions result in immediate
fatals instead of passing the error up (kills ~300 lines).

Implement sending of the QUIT command which replaces crude close(2).

tested by gilles@, todd@


# 1.12 11-Nov-2009 chl

add missing headers needed by time()

ok jacekm@


# 1.11 05-Nov-2009 jsing

Include a Date: header in bounce messages.

ok jacekm@ gilles@


# 1.10 05-Nov-2009 jsing

Introduce a 6yz status code, used internally to report permanent errors.
The 1yz and 6yz status codes are now removed prior to reporting the status
message in bounce messages, which provides an easy way to distinguish
between local and remote status messages. Initial diff from jacekm@

ok gilles@ jacekm@


# 1.9 16-Sep-2009 jacekm

Free resources when bounce enqueue fails due to a timeout.


# 1.8 15-Sep-2009 jacekm

Extend SMTP client_* API to support SSL+AUTH, and use it in the mta
process to relay mails. ok gilles@


# 1.7 04-Sep-2009 jacekm

Fix scheduling of bounces that could not be delivered.
ok gilles@


# 1.6 27-Aug-2009 jacekm

Implement client side of the SMTP protocol in a library-like module.
Make bounce code and /usr/sbin/sendmail interface use this new API.
The mta process continues to use its own implementation, but
eventually will be switched to use this shared module.

Buffer routines are taken from buffer.c rather than from evbuffer.
This is one step forward to using a single buffer API across the
program.

"it looks sexy" gilles@


# 1.5 06-Aug-2009 gilles

when writing a bounce, follow the same rule as for mta sessions and prepend
with a dot lines starting with a dot


# 1.4 06-Aug-2009 gilles

factorize file_copy_session() and file_copy() so file_copy() can handle
both deliveries to mailboxes (mbox/maildir) and copying to a session.


# 1.3 06-Aug-2009 gilles

fix a typo in bounce message t -> to


# 1.2 06-Aug-2009 gilles

- introduce message_set_errormsg() to set the error description that will
appear in a bounce message, and message_get_errormsg() to retrieve that
message.
- when loop is detected, call message_set_errormsg()
- in mta, call message_set_errormsg() for each recipient failure
- in mta, call message_set_errormsg() to copy batch errors to recipients if
we failed to deliver for a session related error
- when bouncing, add the recipient and error reason to the bounce message


# 1.1 06-Aug-2009 gilles

This commit reworks the entire mailer daemon support to actually make it
work for real. As an added bonus, it simplifies it, makes it follow the
same code path as regular messages and kills quite some code from mta,
mda and store. There's still some work needed but the most painful part
is behind us now ;)

ok jacekm@