[Pymilter] simple milter design needed

Stuart D. Gathman stuart at bmsi.com
Sun Apr 4 16:08:26 EDT 2004


On Sat, 3 Apr 2004, Eric S. Johansson wrote:

> > # The connect callback tells you connecting IP.  Furthermore, the connect
> > # interface is available as a "macro".
> 
> If I'm interpreting this correctly, it is presenting the address of the 
>   host initiating the smtp transaction.  I need to know something 
> different which is which interface the message arrives on not where it 
> came from.  reason being that I perform asymectric operation on the mail 

The if_name macro tells you that, I believe.  The if_addr macro tells
you the destination IP the message arrived on.  These are distinct from
the parameters passed to the connect callback, which tell you which
host name and IP the connect came from.  The getsymval hack provides
a way to get arbitrary data that wasn't thought of when the basic API
was designed (e.g. interface the message arrives on).  If necessary,
you can gather any information you need in sendmail-cf code and pass it
via a named macro.  Sendmail.cf defines which macros are available to milters.
You can call an arbitrary program in any language to gather said 
information via a program map if the cf language is not sufficient
(or looks too much like chicken scratches).

> is class instance preserved between callbacks making self a safe place 
> to accumulate data?  missed the docs on that.  also occurs to me to 

Yes.  That is the point of the OO layer provided by Milter.py.  Also, the
connection object is discarded after calling close - unless you leave 
a reference around somewhere.  Note that the connection object lifetime
spans a connection - which can involve any number of messages.  Each
call to envfrom starts a new message.

> wonder how/if you transion between C threads and python threads.  also 

Secret incantations gathered from careful study of the Python/C API, and
a few offerings to the Python gods on comp.lang.python.

The key API is the following:

  PyThreadState *t = PyThreadState_New(interp);
  if (t == NULL) return NULL;
  PyEval_AcquireThread(t); /* lock interp and assign to current thread */

> wonder about mem leaks and how to detect/recover.  camram usually is 
> spawned by procmail and never lives for more than 1 process lifetime.
> hmm I clearly have some work to do.

Python is garbage collected, and the C milter module has been very tight
after the last two leaks plugged by Alexander.  And those leaks were small.
I run milter for months with 400 msgs/hr.  Alexander runs at 10 times 
that load.

As long as you don't keep adding to a global collection (a situation
I call "data cancer" and not a true memory leak), it is all automatic
(barring bugs in Python or a C module).

-- 
			Stuart D. Gathman <stuart at bmsi.com>
      Business Management Systems Inc.  Phone: 703 591-0911 Fax: 703 591-6154
      "Very few of our customers are going to have a pure Unix
      or pure Windows environment." - Dennis Oldroyd, Microsoft Corporation




More information about the Pymilter mailing list