eric256 has asked for the wisdom of the Perl Monks concerning the following question:

Hey,

I'm using spampd as a proxy for incoming SMTP connections to filter and tag spam before it gets to my exchange server. This works well, when it is working. However occasionaly it stops making the proxy connection. At least I think thats whats happening When it "hangs" I can still telnet to it and it accepts my connection but I don't get the banner from my actual SMTP server, in fact i don't get any banner at all.

The reason I'm asking here is because spampd is a perl script that uses Net::Server::PreForkSimple and I'm hoping someone will recognize this problem, or have some idea how i can at least force it to revive itself when it gets in this state.

When it begins behaving like this I see

Jan 8 18:43:50 SPAM2 spampd[19137]: WARNING!! Error in process_reques +t eval block: Child server process timed out!
in the logs. Restarting the process solves the problem and it works agian.


___________
Eric Hodges

Replies are listed 'Best First'.
Re: spampd hangs occasionaly
by jettero (Monsignor) on Jan 08, 2007 at 21:53 UTC

    I'm just guessing, but I'd say you might need to prefork a few hundred kids to deal with the botnet swarms that invariably come looking for your valid RCPTs. That may not be the problem, but it's definitely a possibility — maybe a deadlock? What platform are you in? I've had some success with the milter-spamd combo and doing it from procmail on a mass scale... Perhaps spampd isn't ready for primetime? I never tried it, no idea...

    -Paul

      Yea I'm not convinced its the best setup. Any pointers on trying procmail/spamd? BTW This is RedHat 9.0 Shrike and SpamAssassin version 3.1.7 running on Perl version 5.8.0.


      ___________
      Eric Hodges
Re: spampd hangs occasionaly
by shmem (Chancellor) on Jan 09, 2007 at 10:20 UTC
    That message comes from a piece of code in spampd which looks suspicious to me:
    sub process_request { my $self = shift; my $msg; eval { local $SIG{ALRM} = sub { die "Child server process timed out!\n" + }; my $timeout = $self->{spampd}->{childtimeout}; # start a timeout alarm alarm($timeout); # start an smtp server my $smtp_server = SpamPD::Server->new($self->{server}->{client}) +; ... #close the temp file $smtp_server->{data}->close or $self->log(1, ... ); ... # close connections $client->{sock}->close or die "Couldn't close client->{sock}: $!"; $smtp_server->{sock}->close or die "Couldn't close smtp_server->{sock}: $! +"; if ( $self->{spampd}->{debug} ) { $self->log(2, "Closed connections"); } }; # end eval block alarm(0); # stop the timer # check for error in eval block if ($@ ne '') { chomp($@); $msg = "WARNING!! Error in process_request eval block: $@"; $self->log(0, $msg); die ($msg . "\n"); } $self->{spampd}->{instance}++; }

    Just calling die from an alarm handler inside eval, only to propagate $@, without any cleanup whatsoever (closing filehandles, destroying objects, removing tempfiles) doesn't seem like the right thing to do here, imho. The (second part of your) problem could well stem from here: abandoned open connections that can't be reused - that might be why spampd isn't responsive after a timeout.

    This might help:

    • after allocating my $smtp_server replace the alarm handler with a new anonymous sub that calls $smtp_server->{sock}->close
    • same after my $client = SpamPD::Client->new, with cleanup of client connection also

    but maybe the bug is elsewhere.. ;-)

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: spampd hangs occasionaly
by madbombX (Hermit) on Jan 09, 2007 at 04:35 UTC
    I have an email gateway setup as well to protect my Exchange server. However, I use amavisd-new and Spamassassin directly on the server. This way I am not attempting to examine messages that may be rejected due to an invalid user or bounce, etc. etc.

    I can't speak towards your issue, but have you considered running spamassassin in a non-proxy setup? It may fix the issue.

Re: spampd hangs occasionaly
by eric256 (Parson) on Jan 09, 2007 at 21:14 UTC

    I think I figured it out. Hopefully this will help anyone out with a similar issue. Thanks to shmem I started looking at the connection between spampd and Exchange. It turns out that Exchange defaults to only allowing 20 emails per connections, while Net::Server::PreForkSimple defaults to 1000 requests per connection. So after the first 20 messages per child each child was failing 980 times before restarting to then start accepting mail agian. At least that's what appears to be happening I reduced the Net::Server::PreForkSimple to only doing 5 requests per child and boosted exchange to all 50 and we'll see what happens. If it works then I can fine tune the two closer to each others settings to hopefully get some more performance out if it. Here's crossing my fingers and toes!


    ___________
    Eric Hodges

      Just an update for anyone who comes across this in the future. In the end I had to give up on SpamPD and use a combination of PostFix + SpamD instead. This works better, faster, safer, more consitently and is actually not that horrible to setup!


      ___________
      Eric Hodges