Karl O. Pinc wrote:

On 09/09/2008 04:48:47 PM, Wietse Venema wrote:

Instead of guessing, run a network sniffer that captures the
packet content.

Thank you.  I knew someone would send a good idea my way.

Here's what I found:

Nc seems to be left hanging when there's more than
one subscriber to the email list; when two messages
go through the filter nc is left hanging after
the second pair TCP sessions.

Normally as the filter runs the process tree running
the mailman-filter filter looks like this:


11530 ? S 0:00 \_ spawn -l -n 127.0.0.1:11025 -t inet user=mfilter 11626 ? Ss 0:00 | \_ /bin/sh /usr/local/sbin/mailman-filter 127.0. 11627 ? S 0:00 | \_ awk -W Interactive BEGIN {headers = 1;?
11628 ?        R      0:00  |       \_ nc 127.0.0.1 11026


With one subscriber, the smtp end sends a packet with a
bunch of SMTP protocol ending with a DATA command,
gets back a bunch of 250 Oks and a 354 reply,
sends the message, ends with a period and then
a QUIT in the same packet, gets back a 250 (queued) reply
and  a 221 (bye) in the same packet.  Then
both the smtp and the smtpd ends close the tcp socket
and awk gets a EOF and ends and nc shuts down as well.
Just as expected.

When there's more than one subscriber the same thing
happens for mail sent to the first subscriber, but
then the same message is sent to the second subscriber.
Again, smtp sends a DATA command, gets back a 354,

if there is one message, then there is one DATA command. there is no subscriber concept in smtp.

BTW, if all you want is to remove the Sender header, then a header_checks is enough
/^(Sender: .*)/ REPLACE X-$1

but rewriting/removing the Sender header because of MUA brokerage is not wise.


sends the message, ends with a period, and gets
a 250 reply back.  At that point things have changed
because the smtp side does not send a QUIT, instead it
closes it's side of the TCP connection with a FIN, ACK.
I presume that at this point spawn sends awk an EOF on stdin
because the process tree then looks like this:

11530 ? S 0:00 \_ spawn -l -n 127.0.0.1:11025 -t inet user=mfilter 11537 ? Ss 0:00 | \_ /bin/sh /usr/local/sbin/mailman-filter 127.0.
11539 ?        S      0:00  |       \_ nc 127.0.0.1 11026

Spawn does not close it's side of the tcp connection
initiated by smtp.

The system stays in this state for 5 minutes until smtpd
times out.  Then smtpd sends a 421 (timeout exceeded)
back to nc, which sends it to stdout to spawn and
it goes back to smtp.  At that point smtp sends a RST
packet back to spawn and the connection is shut down.
Then smtpd sends a FIN, ACK back to nc, which responds
with it's own FIN, ACK and with a final ACK from smtpd
that side of the filter shuts down gracefully.

So (I think) the question becomes why smtp does not
send a QUIT to end delivery of the 2nd email as it
does the first.


Attached are 4 tcpdumps.  For testing I've used ports
11025 (for spawn) and 11026 (for smtpd) rather than
the 10025 and 10026 documented in my script and in
FILTER_README.

Two files record nc "hanging" there are 2 recipients
of the mailing list.

smtp_side2  Traffic between smtp and spawn.
smtpd_side2 Traffic between spawn (nc) and smtpd.

Two files record a "normal" filter event, there
is only 1 recipient of the mailing list message.

smtp_side3  Traffic between smtp and spawn.
smtpd_side3 Traffic between spawn and smtpd.

Thanks for the help.



Karl <[EMAIL PROTECTED]>
Free Software:  "You don't pay back, you pay forward."
                 -- Robert A. Heinlein

Reply via email to