INN commit: trunk/innd (nc.c)

INN Commit Russ_Allbery at isc.org
Wed Mar 18 20:14:50 UTC 2009


    Date: Wednesday, March 18, 2009 @ 13:14:48
  Author: iulius
Revision: 8386

When paused or throttled, do not hang incoming connections
(nnrpd was hanging without responding to a client trying
to post an article).

Thanks to Ray Banana for the bug report.

Modified:
  trunk/innd/nc.c

------+
 nc.c |   83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 71 insertions(+), 12 deletions(-)

Modified: nc.c
===================================================================
--- nc.c	2009-03-17 17:51:40 UTC (rev 8385)
+++ nc.c	2009-03-18 20:14:48 UTC (rev 8386)
@@ -202,14 +202,31 @@
 static void
 NCpostit(CHANNEL *cp)
 {
-  bool	postok;
   const char	*response;
   char	buff[SMBUF];
 
+  if (Mode == OMthrottled) {
+    cp->Reported++;
+    NCwriteshutdown(cp, ModeReason);
+    return;
+  } else if (Mode == OMpaused) {
+    cp->Reported++;
+    cp->State = CSgetcmd;
+    /* In streaming mode, there is no NNTP_FAIL_TAKETHIS_DEFER and we must
+     * not reject the article. */
+    if (cp->Sendid.size > 3)
+      snprintf(buff, sizeof(buff), "%d %s", NNTP_FAIL_ACTION, ModeReason);
+    else
+      snprintf(buff, sizeof(buff), "%d %s", NNTP_FAIL_IHAVE_DEFER, ModeReason);
+    response = buff;
+    NCwritereply(cp, response);
+    return;
+  }
+
   /* Note that some use break, some use return here. */
-  if ((postok = ARTpost(cp)) != 0) {
+  if (ARTpost(cp)) {
     cp->Received++;
-    if (cp->Sendid.size > 3) { /* We be streaming */
+    if (cp->Sendid.size > 3) { /* We are streaming. */
       cp->Takethis_Ok++;
       snprintf(buff, sizeof(buff), "%d", NNTP_OK_TAKETHIS);
       cp->Sendid.data[0] = buff[0];
@@ -219,6 +236,8 @@
     } else
       response = NNTP_TOOKIT;
   } else {
+    /* The answer to TAKETHIS is a response code followed by a
+     * message-ID.  The response code is already NNTP_FAIL_TAKETHIS_REJECT. */
     if (cp->Sendid.size)
       response = cp->Sendid.data;
     else
@@ -236,10 +255,7 @@
     cp->Duplicate, buff);
     cp->Reported = 0;
   }
-  if (Mode == OMthrottled) {
-    NCwriteshutdown(cp, ModeReason);
-    return;
-  }
+
   cp->State = CSgetcmd;
   NCwritereply(cp, response);
 }
@@ -287,6 +303,7 @@
     char	        *p;
     TOKEN		token;
     ARTHANDLE		*art;
+    char                *buff = NULL;
 
     /* Snip off the Message-ID. */
     for (p = cp->In.data + cp->Start + strlen("head"); ISWHITE(*p); p++)
@@ -295,6 +312,16 @@
     if (NCbadid(cp, p))
 	return;
 
+    if (Mode == OMthrottled) {
+        NCwriteshutdown(cp, ModeReason);
+        return;
+    } else if (Mode == OMpaused) {
+        xasprintf(&buff, "%d %s", NNTP_FAIL_ACTION, ModeReason);
+        NCwritereply(cp, buff);
+        free(buff);
+        return;
+    }
+
     /* Get the article token and retrieve it. */
     if (!HISlookup(History, p, NULL, NULL, NULL, &token)) {
 	NCwritereply(cp, NNTP_DONTHAVEIT);
@@ -336,6 +363,16 @@
     if (NCbadid(cp, p))
 	return;
 
+    if (Mode == OMthrottled) {
+        NCwriteshutdown(cp, ModeReason);
+        return;
+    } else if (Mode == OMpaused) {
+        xasprintf(&buff, "%d %s", NNTP_FAIL_ACTION, ModeReason);
+        NCwritereply(cp, buff);
+        free(buff);
+        return;
+    }
+
     /* Get the article filenames; open the first file (to make sure
      * the article is still here). */
     if (!HISlookup(History, p, NULL, NULL, NULL, &token)) {
@@ -454,6 +491,7 @@
 NCihave(CHANNEL *cp)
 {
     char	*p;
+    char        *buff = NULL;
 #if defined(DO_PERL) || defined(DO_PYTHON)
     char	*filterrc;
     size_t	msglen;
@@ -467,6 +505,17 @@
     if (NCbadid(cp, p))
 	return;
 
+    if (Mode == OMthrottled) {
+        NCwriteshutdown(cp, ModeReason);
+        return;
+    } else if (Mode == OMpaused) {
+        cp->Ihave_Deferred++;
+        xasprintf(&buff, "%d %s", NNTP_FAIL_IHAVE_DEFER, ModeReason);
+        NCwritereply(cp, buff);
+        free(buff);
+        return;
+    }
+
     if ((innconf->refusecybercancels) && (strncmp(p, "<cancel.", 8) == 0)) {
 	cp->Refused++;
 	cp->Ihave_Cybercan++;
@@ -954,6 +1003,8 @@
 	cp->State = CSgetcmd;
 	cp->Start = cp->Next;
 	NCclearwip(cp);
+        /* The answer to TAKETHIS is a response code followed by a
+         * message-ID. */
 	if (cp->Sendid.size > 3)
 	  NCwritereply(cp, cp->Sendid.data);
 	else
@@ -968,11 +1019,7 @@
 	 may also include command line */
       readmore = false;
       movedata = false;
-      if (Mode == OMpaused) { /* defer processing while paused */
-	RCHANremove(cp); /* don't bother trying to read more for now */
-	SCHANadd(cp, Now.tv_sec + innconf->pauseretrytime, &Mode, NCproc, NULL);
-	return;
-      } else if (Mode == OMthrottled) {
+      if (Mode == OMthrottled) {
 	/* Clear the work-in-progress entry. */
 	NCclearwip(cp);
 	NCwriteshutdown(cp, ModeReason);
@@ -1306,6 +1353,7 @@
 NCcheck(CHANNEL *cp)
 {
     char		*p;
+    char                *buff = NULL;
     size_t		idlen, msglen;
 #if defined(DO_PERL) || defined(DO_PYTHON)
     char		*filterrc;
@@ -1343,6 +1391,17 @@
 	return;
     }
 
+    if (Mode == OMthrottled) {
+        NCwriteshutdown(cp, ModeReason);
+        return;
+    } else if (Mode == OMpaused) {
+        cp->Check_deferred++;
+        xasprintf(&buff, "%d %s", NNTP_FAIL_CHECK_DEFER, ModeReason);
+        NCwritereply(cp, buff);
+        free(buff);
+        return;
+    }
+
 #if defined(DO_PERL)
     /*  Invoke a perl message filter on the message ID. */
     filterrc = PLmidfilter(p);




More information about the inn-committers mailing list