xref: /freebsd/contrib/sendmail/libmilter/docs/overview.html (revision d39bd2c1388b520fcba9abed1932acacead60fba)
1 <HTML>
2 <HEAD>
3 <TITLE>Technical Overview</TITLE>
4 </HEAD>
5 <BODY>
6 <!--
7 $Id: overview.html,v 1.22 2013-11-22 20:51:39 ca Exp $
8 -->
9 
10 <H1>Technical Overview</H1>
11 
12 <H2>Contents</H2>
13 
14 <UL>
15     <LI><A HREF="#Initialization">Initialization</A>
16     <LI><A HREF="#ControlFlow">Control Flow</A>
17     <LI><A HREF="#Multithreading">Multithreading</A>
18     <LI><A HREF="#ResourceManagement">Resource Management</A>
19     <LI><A HREF="#SignalHandling">Signal Handling</A>
20 </UL>
21 
22 <H2><A NAME="Initialization">Initialization</A></H2>
23 
24 In addition to its own initialization,
25 libmilter expects a filter to initialize several parameters
26 before calling <A HREF="smfi_main.html">smfi_main</A>:
27 <UL>
28     <LI>The callbacks the filter wishes to be called, and the types of
29     message modification it intends to perform (required, see
30     <A HREF="smfi_register.html">smfi_register</A>).
31 
32     <LI>The socket address to be used when communicating with the MTA
33     (required, see <A HREF="smfi_setconn.html">smfi_setconn</A>).
34 
35     <LI>The number of seconds to wait for MTA connections before
36     timing out (optional, see
37     <A HREF="smfi_settimeout.html">smfi_settimeout</A>).
38 </UL>
39 <P>
40 If the filter fails to initialize libmilter,
41 or if one or more of the parameters it has passed are invalid,
42 a subsequent call to smfi_main will fail.
43 
44 <H2><A NAME="ControlFlow">Control Flow</A></H2>
45 
46 <P>
47 The following pseudocode describes the filtering process from the
48 perspective of a set of <CODE>N</CODE> MTA's,
49 each corresponding to a connection.
50 Callbacks are shown beside the processing stages in which they are invoked;
51 if no callbacks are defined for a particular stage,
52 that stage may be bypassed.
53 Though it is not shown,
54 processing may be aborted at any time during a message,
55 in which case the
56 <A HREF="xxfi_abort.html">xxfi_abort</A> callback is invoked and control
57 returns to <CODE>MESSAGE</CODE>.
58 <P>
59 <PRE>
60 For each of N connections
61 {
62 	For each filter
63 		negotiate MTA/milter capabilities/requirements (<A HREF="xxfi_negotiate.html">xxfi_negotiate</A>)
64 	For each filter
65 		process connection (<A HREF="xxfi_connect.html">xxfi_connect</A>)
66 	For each filter
67 		process helo/ehlo (<A HREF="xxfi_helo.html">xxfi_helo</A>)
68 MESSAGE:For each message in this connection (sequentially)
69 	{
70 		For each filter
71 			process sender (<A HREF="xxfi_envfrom.html">xxfi_envfrom</A>)
72 		For each recipient
73 		{
74 			For each filter
75 				process recipient (<A HREF="xxfi_envrcpt.html">xxfi_envrcpt</A>)
76 		}
77 		For each filter
78 			process DATA (<A HREF="xxfi_data.html">xxfi_data</A>)
79 		For each filter
80 		{
81 			For each header
82 				process header (<A HREF="xxfi_header.html">xxfi_header</A>)
83 			process end of headers (<A HREF="xxfi_eoh.html">xxfi_eoh</A>)
84 			For each body block
85 				process this body block (<A HREF="xxfi_body.html">xxfi_body</A>)
86 			process end of message (<A HREF="xxfi_eom.html">xxfi_eom</A>)
87 		}
88 	}
89 	For each filter
90 		process end of connection (<A HREF="xxfi_close.html">xxfi_close</A>)
91 }
92 </PRE>
93 
94 <P>Note: Filters are contacted in order defined in config file.</P>
95 
96 <P>
97 To write a filter, a vendor supplies callbacks to process relevant
98 parts of a message transaction.
99 The library then controls all sequencing, threading,
100 and protocol exchange with the MTA.
101 <A HREF="#figure-3">Figure 3</A> outlines control flow for a filter
102 process, showing where different callbacks are invoked.
103 </P>
104 
105 <DIV ALIGN="center"><A NAME="figure-3"></A>
106 <TABLE border=1 cellspacing=0 cellpadding=2 width="70%">
107 <TR bgcolor="#dddddd"><TH>SMTP Commands</TH><TH>Milter Callbacks</TH></TR>
108 <TR><TD>(open SMTP connection)</TD><TD>xxfi_connect</TD></TR>
109 <TR><TD>HELO ...</TD><TD>xxfi_helo</TD></TR>
110 <TR><TD>MAIL From: ...</TD><TD>xxfi_envfrom</TD></TR>
111 <TR><TD>RCPT To: ...</TD><TD>xxfi_envrcpt</TD></TR>
112 <TR><TD>[more RCPTs]</TD><TD>[xxfi_envrcpt]</TD></TR>
113 <TR><TD>DATA</TD><TD>xxfi_data</TD></TR>
114 <TR><TD>Header: ...</TD><TD>xxfi_header</TD></TR>
115 <TR><TD>[more headers]</TD><TD>[xxfi_header]</TD></TR>
116 <TR><TD>&nbsp;</TD><TD>xxfi_eoh</TD></TR>
117 <TR><TD>body... </TD><TD>xxfi_body</TD></TR>
118 <TR><TD>[more body...]</TD><TD>[xxfi_body]</TD></TR>
119 <TR><TD>.</TD><TD>xxfi_eom</TD></TR>
120 <TR><TD>QUIT</TD><TD>xxfi_close</TD></TR>
121 <TR><TD>(close SMTP connection)</TD><TD>&nbsp;</TD></TR>
122 </TABLE>
123 <B>Figure 3: Milter callbacks related to an SMTP transaction.</B>
124 </DIV>
125 
126 <P>
127 Note that although only a single message is shown above, multiple
128 messages may be sent in a single connection.
129 Note also that a message or connection may be aborted by
130 either the remote host or the MTA
131 at any point during the SMTP transaction.
132 If this occurs during a message (between the MAIL command and the final "."),
133 the filter's
134 <A HREF="xxfi_abort.html">xxfi_abort</A> routine will be called.
135 <A HREF="xxfi_close.html">xxfi_close</A> is called any time the
136 connection closes.
137 
138 <H2><A NAME="Multithreading">Multithreading</A></H2>
139 
140 <P>
141 A single filter process may handle any number of connections
142 simultaneously.
143 All filtering callbacks must therefore be reentrant,
144 and use some appropriate external synchronization methods to access
145 global data.
146 Furthermore, since there is not a one-to-one correspondence
147 between threads and connections
148 (N connections mapped onto M threads, M &lt;= N),
149 connection-specific data must be accessed
150 through the handles provided by the Milter library.
151 The programmer cannot rely on library-supplied thread-specific data blocks
152 (e.g., <CODE>pthread_getspecific(3)</CODE>) to store connection-specific data.
153 See the API documentation for
154 <A HREF="smfi_setpriv.html">smfi_setpriv</A> and
155 <A HREF="smfi_getpriv.html">smfi_getpriv</A> for details.
156 
157 <H2><A NAME="ResourceManagement">Resource Management</A></H2>
158 
159 Since filters are likely to be long-lived,
160 and to handle many connections,
161 proper deallocation of per-connection resources is important.
162 The lifetime of a connection is bracketed by calls to the
163 callbacks <A HREF="xxfi_connect.html">xxfi_connect</A> and
164 <A HREF="xxfi_close.html">xxfi_close</A>.
165 Therefore connection-specific
166 resources (accessed via <A HREF="smfi_getpriv.html">smfi_getpriv</A>
167 and <A HREF="smfi_setpriv.html">smfi_setpriv</A>) may be allocated in
168 <A HREF="xxfi_connect.html">xxfi_connect</A>,
169 and should be freed in
170 <A HREF="xxfi_close.html">xxfi_close</A>.
171 For further information see
172 the <A HREF="api.html#conn-msg">discussion</A> of message- versus
173 connection-oriented routines.
174 In particular,
175 note that there is only one connection-specific data pointer per connection.
176 <P>
177 
178 Each message is bracketed by calls to
179 <A HREF="xxfi_envfrom.html">xxfi_envfrom</A> and
180 <A HREF="xxfi_eom.html">xxfi_eom</A> (or
181 <A HREF="xxfi_abort.html">xxfi_abort</A>),
182 implying that message-specific resources can be allocated
183 and reclaimed in these routines.
184 Since the messages in a connection are processed sequentially by each filter,
185 there will be only one active message associated with a given
186 connection and filter (and connection-private data block).
187 These resources must still be accessed through
188 <A HREF="smfi_getpriv.html">smfi_getpriv</A> and
189 <A HREF="smfi_setpriv.html">smfi_setpriv</A>,
190 and must be reclaimed in
191 <A HREF="xxfi_abort.html">xxfi_abort</A>.
192 
193 <H2><A NAME="SignalHandling">Signal Handling</A></H2>
194 
195 libmilter takes care of signal handling,
196 the filters are not influenced directly by signals.
197 There are basically two types of signal handlers:
198 
199 <OL>
200 <LI><TT>Stop</TT>: no new connections from the MTA will be accepted,
201 but existing connections are allowed to continue.
202 <LI><TT>Abort</TT>: all filters will be stopped as soon as the next
203 communication with the MTA happens.
204 </OL>
205 
206 Filters are not terminated asynchronously
207 (except by signals that can't be caught).
208 In the case of <TT>Abort</TT> the
209 <A HREF="xxfi_abort.html">xxfi_abort</A> callback is usually invoked
210 if there is an active transaction.
211 However, if an invoked callback takes too long to execute
212 (the maximum time <TT>Abort</TT> waits is currently 5s)
213 <!-- XREF: MI_CHK_TIME -->
214 then the filter is simply terminated, i.e.,
215 neither the
216 <A HREF="xxfi_abort.html">xxfi_abort</A> callback
217 nor the
218 <A HREF="xxfi_close.html">xxfi_close</A> callback
219 is invoked.
220 
221 <HR size="1">
222 <FONT size="-1">
223 Copyright (c) 2000, 2001, 2003, 2006, 2018 Proofpoint, Inc. and its suppliers.
224 All rights reserved.
225 <BR>
226 By using this file, you agree to the terms and conditions set
227 forth in the LICENSE.
228 </FONT>
229 </BODY>
230 </HTML>
231