Peter J. Holzer escribió:
On 2008-04-24 18:49:39 -0400, Matt Sergeant wrote:
I think the core used to do something like this:

Index: lib/Qpsmtpd.pm
===================================================================
--- lib/Qpsmtpd.pm      (revision 876)
+++ lib/Qpsmtpd.pm      (working copy)
@@ -390,7 +390,10 @@
     if ($hooks->{$hook}) {
         my @r;
         for my $code (@{$hooks->{$hook}}) {
+            $SIG{ALRM} = sub { die "Alarm" };
+            my $prev = alarm(10); # should be long enough for anyone!

You haven't tried ClamAV on a 300 MHz SPARC ;-)

eval { (@r) = $code->{code}->($self, $self-
transaction, @_); };
+            alarm($prev);
[...]
But I removed it because then alarm() features VERY heavily in the performance profiling as an expensive system call.

Also I'm not sure that would help in Jose's case. The problem seems to
happen either while trying to read the truncated DATA line or more
likely while writing the 354 response to the data command. The first is already protected by a (long) timeout, but the second isn't.
Jose, can you try this patch?

Index: lib/Qpsmtpd/TcpServer.pm
===================================================================
--- lib/Qpsmtpd/TcpServer.pm    (revision 876)
+++ lib/Qpsmtpd/TcpServer.pm    (working copy)
@@ -109,7 +111,9 @@
     $self->log(LOGINFO, $line);
     $buf .= "$line\r\n";
   }
+  my $prev = alarm(10);
   print $buf or ($self->log(LOGERROR, "Could not print [$buf]: $!"), return 0);
+  alarm($prev);
   return 1;
 }


You caught it!!! It did the trick!

3390 451 Incomplete DATA
print() on closed filehandle GEN1 at /usr/bin/qpsmtpd-forkserver line 288.
3390 Connection Timed Out

Line 288 in qpsmtp-forkserver is:

287     $SIG{ALRM} = sub {
288        print $client "421 Connection Timed Out\n";
289        ::log(LOGINFO, "Connection Timed Out");
290        exit; };

But why is it the bug only reproducable when using TLS and a plugin that connecets via DBI? How are these two modules interacting to cause such pain?

And why is the code retrying all those writes? sub respond seems to not be made to do retry writes...

Investigating more: change respond for "log" in SMTP.pm and the bug disappears!!! (the patch that you propose is not needed anymore).

  unless ( $complete ) {
      $self->log(LOGINFO, "Incomplete DATA");
      #$self->respond(451, "Incomplete DATA");
      $self->reset_transaction; # clean up after ourselves
      return 1;
  }

So it looks like the respond method has something to do with the bug... If you uncomment $self->respond... the bug starts again!

Jose Luis Martinez
CAPSiDE
[EMAIL PROTECTED]

Reply via email to