INN commit: branches/2.4/nnrpd (line.c)

INN Commit Russ_Allbery at isc.org
Thu Apr 10 19:59:21 UTC 2008


    Date: Thursday, April 10, 2008 @ 12:59:21
  Author: iulius
Revision: 7756

It seems that the SSL_read cannot be mixed with select()
as in the current code.  SSL communicates in its own data
blocks and hand shaking.  The do_readline using SSL_read
could return, but still with a partial line in the SSL_read
buffer.  Then the server SSL routine would sit there waiting
for completion of that data block while nnrpd sat at the
select() routine waiting for more data from the server.

(Without this patch, clients like Thunderbird, SeaMonkey
or slrn sometimes hang when posting using a SSL connection.)

Here, we decide to just bypass the select() wait.  Unlike
innd with multiple threads, the select on nnrpd is just
waiting on a single file descriptor, so it is not really
essential with blocked read like SSL_read.  Using an alarm
signal around SSL_read for non active timeout, SSL works
without dead locks.  However, without the select() wait,
the IDLE timer stat won't be collected...

Patch from Kachun Lee.

Modified:
  branches/2.4/nnrpd/line.c

--------+
 line.c |   61 ++++++++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 42 insertions(+), 19 deletions(-)

Modified: line.c
===================================================================
--- line.c	2008-04-10 19:58:51 UTC (rev 7755)
+++ line.c	2008-04-10 19:59:21 UTC (rev 7756)
@@ -141,27 +141,50 @@
 		    line->allocated = newsize;
 		}
 	    }
-	    /* wait for activity on stdin, updating timer stats as we
-	     * go */
-	    do {
-		struct timeval t;
 
-		FD_ZERO(&rmask);
-		FD_SET(STDIN_FILENO, &rmask);
-		t.tv_sec = timeout;
-		t.tv_usec = 0;
-		TMRstart(TMR_IDLE);
-		i = select(STDIN_FILENO + 1, &rmask, NULL, NULL, &t);
-		TMRstop(TMR_IDLE);
-		if (i == -1 && errno != EINTR) {
-		    syswarn("%s can't select", ClientHost);
-		    return RTtimeout;
-		}
-	    } while (i == -1);
+#ifdef HAVE_SSL
+            /* It seems that the SSL_read cannot be mixed with select()
+             * as in the current code.  SSL communicates in its own data
+             * blocks and hand shaking.  The do_readline using SSL_read
+             * could return, but still with a partial line in the SSL_read
+             * buffer.  Then the server SSL routine would sit there waiting
+             * for completion of that data block while nnrpd sat at the
+             * select() routine waiting for more data from the server.
+             *
+             * Here, we decide to just bypass the select() wait.  Unlike
+             * innd with multiple threads, the select on nnrpd is just
+             * waiting on a single file descriptor, so it is not really
+             * essential with blocked read like SSL_read.  Using an alarm
+             * signal around SSL_read for non active timeout, SSL works
+             * without dead locks.  However, without the select() wait,
+             * the IDLE timer stat won't be collected...
+             */
+            if (tls_conn == NULL) {
+#endif
+                /* Wait for activity on stdin, updating timer stats as we
+                 * go. */
+                do {
+                    struct timeval t;
 
-	    /* if stdin didn't select, we must have timed out */
-	    if (i == 0 || !FD_ISSET(STDIN_FILENO, &rmask))
-		return RTtimeout;
+                    FD_ZERO(&rmask);
+                    FD_SET(STDIN_FILENO, &rmask);
+                    t.tv_sec = timeout;
+                    t.tv_usec = 0;
+                    TMRstart(TMR_IDLE);
+                    i = select(STDIN_FILENO + 1, &rmask, NULL, NULL, &t);
+                    TMRstop(TMR_IDLE);
+                    if (i == -1 && errno != EINTR) {
+                        syswarn("%s can't select", ClientHost);
+                        return RTtimeout;
+                    }
+                } while (i == -1);
+
+                /* If stdin didn't select, we must have timed out. */
+                if (i == 0 || !FD_ISSET(STDIN_FILENO, &rmask))
+                    return RTtimeout;
+#ifdef HAVE_SSL
+            }
+#endif
 	    count = line_doread(where,
 				line->allocated - (where - line->start));
 



More information about the inn-committers mailing list