1168515Sgshapiro<HTML>
2168515Sgshapiro<HEAD>
3168515Sgshapiro<TITLE>Technical Overview</TITLE>
4168515Sgshapiro</HEAD>
5168515Sgshapiro<BODY>
690792Sgshapiro<!--
7266692Sgshapiro$Id: overview.html,v 1.22 2013-11-22 20:51:39 ca Exp $
890792Sgshapiro-->
990792Sgshapiro
10168515Sgshapiro<H1>Technical Overview</H1>
1190792Sgshapiro
12168515Sgshapiro<H2>Contents</H2>
1390792Sgshapiro
14168515Sgshapiro<UL>
15168515Sgshapiro    <LI><A HREF="#Initialization">Initialization</A>
16168515Sgshapiro    <LI><A HREF="#ControlFlow">Control Flow</A>
17168515Sgshapiro    <LI><A HREF="#Multithreading">Multithreading</A>
18168515Sgshapiro    <LI><A HREF="#ResourceManagement">Resource Management</A>
19168515Sgshapiro    <LI><A HREF="#SignalHandling">Signal Handling</A>
20168515Sgshapiro</UL>
2190792Sgshapiro
22168515Sgshapiro<H2><A NAME="Initialization">Initialization</A></H2>
2390792Sgshapiro
24168515SgshapiroIn addition to its own initialization,
25168515Sgshapirolibmilter expects a filter to initialize several parameters
26168515Sgshapirobefore calling <A HREF="smfi_main.html">smfi_main</A>:
27168515Sgshapiro<UL>
28168515Sgshapiro    <LI>The callbacks the filter wishes to be called, and the types of
29168515Sgshapiro    message modification it intends to perform (required, see
30168515Sgshapiro    <A HREF="smfi_register.html">smfi_register</A>).
3190792Sgshapiro
32168515Sgshapiro    <LI>The socket address to be used when communicating with the MTA
33168515Sgshapiro    (required, see <A HREF="smfi_setconn.html">smfi_setconn</A>).
3490792Sgshapiro
35168515Sgshapiro    <LI>The number of seconds to wait for MTA connections before
36168515Sgshapiro    timing out (optional, see
37168515Sgshapiro    <A HREF="smfi_settimeout.html">smfi_settimeout</A>).
38168515Sgshapiro</UL>
39168515Sgshapiro<P>
40168515SgshapiroIf the filter fails to initialize libmilter,
41168515Sgshapiroor if one or more of the parameters it has passed are invalid,
42168515Sgshapiroa subsequent call to smfi_main will fail.
4390792Sgshapiro
44168515Sgshapiro<H2><A NAME="ControlFlow">Control Flow</A></H2>
4590792Sgshapiro
46168515Sgshapiro<P>
4790792SgshapiroThe following pseudocode describes the filtering process from the
48168515Sgshapiroperspective of a set of <CODE>N</CODE> MTA's,
49168515Sgshapiroeach corresponding to a connection.
50168515SgshapiroCallbacks are shown beside the processing stages in which they are invoked;
51168515Sgshapiroif no callbacks are defined for a particular stage,
52168515Sgshapirothat stage may be bypassed.
53168515SgshapiroThough it is not shown,
54168515Sgshapiroprocessing may be aborted at any time during a message,
55168515Sgshapiroin which case the
56168515Sgshapiro<A HREF="xxfi_abort.html">xxfi_abort</A> callback is invoked and control
57168515Sgshapiroreturns to <CODE>MESSAGE</CODE>.
58168515Sgshapiro<P>
59168515Sgshapiro<PRE>
6090792SgshapiroFor each of N connections
6190792Sgshapiro{
6290792Sgshapiro	For each filter
63203004Sgshapiro		process connection (<A HREF="xxfi_connect.html">xxfi_connect</A>)
64203004Sgshapiro	For each filter
65203004Sgshapiro		process helo/ehlo (<A HREF="xxfi_helo.html">xxfi_helo</A>)
6690792SgshapiroMESSAGE:For each message in this connection (sequentially)
6790792Sgshapiro	{
6890792Sgshapiro		For each filter
69168515Sgshapiro			process sender (<A HREF="xxfi_envfrom.html">xxfi_envfrom</A>)
7090792Sgshapiro		For each recipient
7190792Sgshapiro		{
7290792Sgshapiro			For each filter
73168515Sgshapiro				process recipient (<A HREF="xxfi_envrcpt.html">xxfi_envrcpt</A>)
7490792Sgshapiro		}
7590792Sgshapiro		For each filter
7690792Sgshapiro		{
77168515Sgshapiro			process DATA (<A HREF="xxfi_data.html">xxfi_data</A>)
7890792Sgshapiro			For each header
79168515Sgshapiro				process header (<A HREF="xxfi_header.html">xxfi_header</A>)
80168515Sgshapiro			process end of headers (<A HREF="xxfi_eoh.html">xxfi_eoh</A>)
8190792Sgshapiro			For each body block
82168515Sgshapiro				process this body block (<A HREF="xxfi_body.html">xxfi_body</A>)
83168515Sgshapiro			process end of message (<A HREF="xxfi_eom.html">xxfi_eom</A>)
8490792Sgshapiro		}
8590792Sgshapiro	}
8690792Sgshapiro	For each filter
87168515Sgshapiro		process end of connection (<A HREF="xxfi_close.html">xxfi_close</A>)
8890792Sgshapiro}
89168515Sgshapiro</PRE>
9090792Sgshapiro
9190792Sgshapiro<P>Note: Filters are contacted in order defined in config file.</P>
9290792Sgshapiro
9390792Sgshapiro<P>
9490792SgshapiroTo write a filter, a vendor supplies callbacks to process relevant
95168515Sgshapiroparts of a message transaction.
96168515SgshapiroThe library then controls all sequencing, threading,
97168515Sgshapiroand protocol exchange with the MTA.
98168515Sgshapiro<A HREF="#figure-3">Figure 3</A> outlines control flow for a filter
9990792Sgshapiroprocess, showing where different callbacks are invoked.
100168515Sgshapiro</P>
101168515Sgshapiro
102168515Sgshapiro<DIV ALIGN="center"><A NAME="figure-3"></A>
103168515Sgshapiro<TABLE border=1 cellspacing=0 cellpadding=2 width="70%">
104168515Sgshapiro<TR bgcolor="#dddddd"><TH>SMTP Commands</TH><TH>Milter Callbacks</TH></TR>
105168515Sgshapiro<TR><TD>(open SMTP connection)</TD><TD>xxfi_connect</TD></TR>
106168515Sgshapiro<TR><TD>HELO ...</TD><TD>xxfi_helo</TD></TR>
107168515Sgshapiro<TR><TD>MAIL From: ...</TD><TD>xxfi_envfrom</TD></TR>
108168515Sgshapiro<TR><TD>RCPT To: ...</TD><TD>xxfi_envrcpt</TD></TR>
109168515Sgshapiro<TR><TD>[more RCPTs]</TD><TD>[xxfi_envrcpt]</TD></TR>
110168515Sgshapiro<TR><TD>DATA</TD><TD>xxfi_data</TD></TR>
111168515Sgshapiro<TR><TD>Header: ...</TD><TD>xxfi_header</TD></TR>
112168515Sgshapiro<TR><TD>[more headers]</TD><TD>[xxfi_header]</TD></TR>
113168515Sgshapiro<TR><TD>&nbsp;</TD><TD>xxfi_eoh</TD></TR>
114168515Sgshapiro<TR><TD>body... </TD><TD>xxfi_body</TD></TR>
115168515Sgshapiro<TR><TD>[more body...]</TD><TD>[xxfi_body]</TD></TR>
116168515Sgshapiro<TR><TD>.</TD><TD>xxfi_eom</TD></TR>
117168515Sgshapiro<TR><TD>QUIT</TD><TD>xxfi_close</TD></TR>
118168515Sgshapiro<TR><TD>(close SMTP connection)</TD><TD>&nbsp;</TD></TR>
119168515Sgshapiro</TABLE>
120168515Sgshapiro<B>Figure 3: Milter callbacks related to an SMTP transaction.</B>
121168515Sgshapiro</DIV>
122168515Sgshapiro
123168515Sgshapiro<P>
12490792SgshapiroNote that although only a single message is shown above, multiple
125168515Sgshapiromessages may be sent in a single connection.
126168515SgshapiroNote also that a message or connection may be aborted by
127168515Sgshapiroeither the remote host or the MTA
128168515Sgshapiroat any point during the SMTP transaction.
129223067SgshapiroIf this occurs during a message (between the MAIL command and the final "."),
130168515Sgshapirothe filter's
131168515Sgshapiro<A HREF="xxfi_abort.html">xxfi_abort</A> routine will be called.
132168515Sgshapiro<A HREF="xxfi_close.html">xxfi_close</A> is called any time the
13390792Sgshapiroconnection closes.
13490792Sgshapiro
135168515Sgshapiro<H2><A NAME="Multithreading">Multithreading</A></H2>
13690792Sgshapiro
137168515Sgshapiro<P>
13890792SgshapiroA single filter process may handle any number of connections
139168515Sgshapirosimultaneously.
140168515SgshapiroAll filtering callbacks must therefore be reentrant,
14190792Sgshapiroand use some appropriate external synchronization methods to access
142168515Sgshapiroglobal data.
143168515SgshapiroFurthermore, since there is not a one-to-one correspondence
144168515Sgshapirobetween threads and connections
145168515Sgshapiro(N connections mapped onto M threads, M &lt;= N),
146168515Sgshapiroconnection-specific data must be accessed
147168515Sgshapirothrough the handles provided by the Milter library.
148168515SgshapiroThe programmer cannot rely on library-supplied thread-specific data blocks
149168515Sgshapiro(e.g., <CODE>pthread_getspecific(3)</CODE>) to store connection-specific data.
150168515SgshapiroSee the API documentation for
151168515Sgshapiro<A HREF="smfi_setpriv.html">smfi_setpriv</A> and
152168515Sgshapiro<A HREF="smfi_getpriv.html">smfi_getpriv</A> for details.
15390792Sgshapiro
154168515Sgshapiro<H2><A NAME="ResourceManagement">Resource Management</A></H2>
15590792Sgshapiro
156168515SgshapiroSince filters are likely to be long-lived,
157168515Sgshapiroand to handle many connections,
158168515Sgshapiroproper deallocation of per-connection resources is important.
159168515SgshapiroThe lifetime of a connection is bracketed by calls to the
160168515Sgshapirocallbacks <A HREF="xxfi_connect.html">xxfi_connect</A> and
161168515Sgshapiro<A HREF="xxfi_close.html">xxfi_close</A>.
162168515SgshapiroTherefore connection-specific
163168515Sgshapiroresources (accessed via <A HREF="smfi_getpriv.html">smfi_getpriv</A>
164168515Sgshapiroand <A HREF="smfi_setpriv.html">smfi_setpriv</A>) may be allocated in
165168515Sgshapiro<A HREF="xxfi_connect.html">xxfi_connect</A>,
166168515Sgshapiroand should be freed in
167168515Sgshapiro<A HREF="xxfi_close.html">xxfi_close</A>.
168168515SgshapiroFor further information see
169168515Sgshapirothe <A HREF="api.html#conn-msg">discussion</A> of message- versus
170168515Sgshapiroconnection-oriented routines.
171168515SgshapiroIn particular,
172168515Sgshapironote that there is only one connection-specific data pointer per connection.
173168515Sgshapiro<P>
17490792Sgshapiro
175168515SgshapiroEach message is bracketed by calls to
176168515Sgshapiro<A HREF="xxfi_envfrom.html">xxfi_envfrom</A> and
177168515Sgshapiro<A HREF="xxfi_eom.html">xxfi_eom</A> (or
178168515Sgshapiro<A HREF="xxfi_abort.html">xxfi_abort</A>),
179168515Sgshapiroimplying that message-specific resources can be allocated
180168515Sgshapiroand reclaimed in these routines.
181168515SgshapiroSince the messages in a connection are processed sequentially by each filter,
18290792Sgshapirothere will be only one active message associated with a given
183168515Sgshapiroconnection and filter (and connection-private data block).
184168515SgshapiroThese resources must still be accessed through
185168515Sgshapiro<A HREF="smfi_getpriv.html">smfi_getpriv</A> and
186168515Sgshapiro<A HREF="smfi_setpriv.html">smfi_setpriv</A>,
187168515Sgshapiroand must be reclaimed in
188168515Sgshapiro<A HREF="xxfi_abort.html">xxfi_abort</A>.
18990792Sgshapiro
190168515Sgshapiro<H2><A NAME="SignalHandling">Signal Handling</A></H2>
19190792Sgshapiro
192168515Sgshapirolibmilter takes care of signal handling,
193168515Sgshapirothe filters are not influenced directly by signals.
19490792SgshapiroThere are basically two types of signal handlers:
19590792Sgshapiro
196168515Sgshapiro<OL>
197168515Sgshapiro<LI><TT>Stop</TT>: no new connections from the MTA will be accepted,
19890792Sgshapirobut existing connections are allowed to continue.
199168515Sgshapiro<LI><TT>Abort</TT>: all filters will be stopped as soon as the next
20090792Sgshapirocommunication with the MTA happens.
201168515Sgshapiro</OL>
20290792Sgshapiro
203168515SgshapiroFilters are not terminated asynchronously
204168515Sgshapiro(except by signals that can't be caught).
20590792SgshapiroIn the case of <TT>Abort</TT> the
206168515Sgshapiro<A HREF="xxfi_abort.html">xxfi_abort</A> callback is invoked.
20790792Sgshapiro
208168515Sgshapiro<HR size="1">
209168515Sgshapiro<FONT size="-1">
210261363SgshapiroCopyright (c) 2000, 2001, 2003, 2006 Proofpoint, Inc. and its suppliers.
21190792SgshapiroAll rights reserved.
212168515Sgshapiro<BR>
21390792SgshapiroBy using this file, you agree to the terms and conditions set
214112810Sgshapiroforth in the LICENSE.
215168515Sgshapiro</FONT>
216168515Sgshapiro</BODY>
217168515Sgshapiro</HTML>
218