Aaron Nabil <[EMAIL PROTECTED]> writes:

] >Has anybody seen this: from time to time, a whole bunch of qmail-queue's
] >will accumulate (I'd say up to ~400), apparently doing nothing (ps shows
] >that most of them have the same WCHAN, but not all of them). Most of
] >them have 1 as PPID, a few still have qmail-smtpd as parent.
] 
] Are they all in TIME_WAIT?  It's probably one machine.

It sure is. As to the TIME_WAIT, this doesn't seem to be a problem
(a "netstat -an" doesn't show to many sockets, in whatever state).

] Look in the logs (or use netstat or lsof) to get the IP address of the
] machine.
] 
] Use my recordio patch to record dialog just for that host.

Thanks, it was very useful.

] I bet you'll find qmail is dropping the connection with the "bare LF" 
] message.  I've previously given my point of view on qmail's non-RFC 
] compliance on the list before, find that message, apply the patch.

You're right about the "bare LF" message. About your patch: if you mean
the one where you just comment out those "if (ch == '\n') straynewline();"
lines, I'm afraid that the exchange following your proposal convinced me
that this isn't the right solution.

BUT, I'm also convinced that the present situation isn't satisfactory. It is
of no comfort to me that the client is the culprit by not following some RFC
if my server is on its knees ! So what can we do to avoid this ? One way
would be not to _exit() in straynewline() but taking care of the state
we're in is barely within the limit of my window of understanding of the
source code. What do you think of this ?:

 ==============================================================================
--- qmail-smtpd.c.orig  Mon Jun 15 12:53:16 1998
+++ qmail-smtpd.c       Wed Aug 18 15:49:57 1999
@@ -47,7 +47,6 @@
 void die_nomem() { out("421 out of memory (#4.3.0)\r\n"); flush(); _exit(1); }
 void die_control() { out("421 unable to read controls (#4.3.0)\r\n"); flush(); 
_exit(1); }
 void die_ipme() { out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); 
flush(); _exit(1); }
-void straynewline() { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); 
flush(); _exit(1); }
 
 void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list 
(#5.7.1)\r\n"); }
 void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed 
rcpthosts (#5.7.1)\r\n"); }
@@ -290,6 +289,8 @@
   qmail_put(&qqt,ch,1);
 }
 
+int straynewline;
+
 void blast(hops)
 int *hops;
 {
@@ -322,17 +323,17 @@
     }
     switch(state) {
       case 0:
-        if (ch == '\n') straynewline();
+        if (ch == '\n') { straynewline = 1; return; }
         if (ch == '\r') { state = 4; continue; }
         break;
       case 1: /* \r\n */
-        if (ch == '\n') straynewline();
+        if (ch == '\n') { straynewline = 1; return; }
         if (ch == '.') { state = 2; continue; }
         if (ch == '\r') { state = 4; continue; }
         state = 0;
         break;
       case 2: /* \r\n + . */
-        if (ch == '\n') straynewline();
+        if (ch == '\n') { straynewline = 1; return; }
         if (ch == '\r') { state = 3; continue; }
         state = 0;
         break;
@@ -379,7 +380,9 @@
   out("354 go ahead\r\n");
  
   received(&qqt,"SMTP",local,remoteip,remotehost,remoteinfo,fakehelo);
+  straynewline = 0;
   blast(&hops);
+  if (straynewline) qmail_fail(&qqt);
   hops = (hops >= MAXHOPS);
   if (hops) qmail_fail(&qqt);
   qmail_from(&qqt,mailfrom.s);
@@ -387,6 +390,7 @@
  
   qqx = qmail_close(&qqt);
   if (!*qqx) { acceptmessage(qp); return; }
+  if (straynewline) { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); 
+return; }
   if (hops) { out("554 too many hops, this message is looping (#5.4.6)\r\n"); return; 
}
   if (databytes) if (!bytestooverflow) { out("552 sorry, that message size exceeds my 
databytes limit (#5.3.4)\r\n"); return; }
   if (*qqx == 'D') out("554 "); else out("451 ");

 ==============================================================================

I said I would not invoke any RFC in vain, but I can't resist :-), I think
this patch is in line with RFC 821, page 26:

     The receiver should not close the transmission channel until
     it receives and replies to a QUIT command (even if there was an
     error).

Another solution for me would be to understand (and fix) why all these
qmail-queue stay around when their father _exit()'s. For example,
shouldn't straynewline() do some clean-up before _exit()'ing ?

Thanks for any advice...


--
  | ~~~~~~~~ Martin Ouwehand ~ Swiss Federal Institute of Technology ~ Lausanne
__|_________ Email/PGP: http://slwww.epfl.ch/SIC/SL/info/Martin.html __________
Educar es vincular la ciencia y la ternura                         [Jos� Mart�]

Reply via email to