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