summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd/ARCHITECTURE
blob: 0214305de1dbcfb843f562d4a27b2f7edd0d5591 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
+==============================+
|The SMTP Daemon Architecture  |
+==============================+

Introduction
------------

The SMTP daemon is a complete mail architecture designed to provide
an MTA and MDA for OpenBSD systems (and others!).

The SMTP daemon is configurable through a simple pf-like syntax to
select external or local delivery and the means to do so.

The SMTP Daemon relies on a fully asynchronous and event based data
transfer model. The IMSG pseudo-protocol is used throughout the daemon
to provide communication between separate privilege-separated
processes.

The following processes are currently implemented:

	* smtp:		The unprivileged SMTP server
	* mfa:		Mail filter agent
	* queue:	A queue scheduler
	* mda:		Local mail delivery agent
	* mta:		Remote mail delivery agent
	* lka:		Lookup agent: handles DNS, db, file and external maps
	* control:	External interaction gateway

The SMTP Server
---------------

The SMTP Server conforms to RFC 5321 and also provides interesting
extensions such as STARTTLS (RFC 2487).


The Mail Filter Agent
---------------------

The mail filter agent has two roles. First it decides if a mail is
allowed to be delivered by the daemon, and then performs resolution
to determine the delivery method that applies to the mail, either
local or remote. The second duty is to perform optional modifications
on the envelope content.


WorkFlow
--------

The base structure that traverses most of smtpd's architecture is a
struct msg. The typical workflow is as shown below from left to right:

+------+                                          +-----+
| SMTP |======+                               +===| MDA |
+------+      |     +-----+     +-------+     |   +-----+
              |=====| MFA |=====| Queue |=====|
                    +-----+     +-------+     |   +-----+
                      ||                      +===| MTA |
                    +-----+                       +-----+
                    | LKA |
                    +-----+


Client -> Server workflow:

1- The message is initially received from either the listening service or
   /usr/sbin/sendmail (for which smtpctl is a link).

2- As envelope is gathered, the information is handed out to MFA for
   validation.

3- MFA takes decision as to whether or not the message can be delivered
   locally or relayed out and notifies SMTP of its decision.

4- If message is not rejected, a file descriptor is requested from QUEUE
   by SMTP which will then write the message to the file descriptor.

5- Once content is written, SMTP notifies QUEUE that the content is
   fully written and provides a list of recipients.

6- QUEUE constructs batches of messages with same message ID and going
   to same destination, and registers them to the batch queue. It then
   writes the information on-disk so that it can recover from a crash
   or shutdown, and notifies SMTP that message is accepted.

7- SMTP notifies client that message was accepted.


Queue workflow:

1- A batch queue traversal is done. For each batch, QUEUE computes the
   retry time based on the number of times it was tried already and
   the time of last attempt. A batch may be in three states:

	a) It is either ready for processing, in which case it is
	   handed to MDA or MTA for delivery attempt.

	b) The delay before next retry has not yet expired, the
	   scheduler will simply ignore it.

	c) The batch age (currently 4 days) has expired. The
	   scheduler will eventually generate a mailer daemon batch
	   and remove the original batch from the queue.


XXX - needs to be completed/improved/updated