Re: One more attempt: stuck processes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Gary Mills wrote:
On Mon, Nov 19, 2007 at 12:35:46PM -0500, Ken Murchison wrote:
Sebastian Hagedorn wrote:
-- Ken Murchison <murch@xxxxxxxxxxxxxx> is rumored to have mumbled on 17. November 2007 11:21:38 -0500 regarding Re: One more attempt: stuck processes:

Here's a patch that seems to fix the problem.  I did some basic testing
(Linux only) to make sure that it doesn't break anything else, but its
always possible that it has some unforseen side effects.  Keep an eye on
it and let me know if you see anything unusual.
Thanks, it seems to be working fine so far! Enjoy your weekend now ...

Gary, have you tried the patch?

On Solaris 9, SO_RCVTIMEO is not mentioned in the setsockopt man page.
My reading tells me that it is defined in the header file, but if it's
actually used, setsockopt() will return an error.  I understand that
this is the case for other operating systems too.  This seems to be a
known problem with setsockopt().  I just checked the Opensolaris source;
it does function there.  This is the code:

 	 case SO_RCVTIMEO:
		if (optlen == sizeof (uint32_t))
	   	      sockets[i].in_timeout = *(uint32_t *)optval;
       	        else {
			errno = EINVAL;
	      	}
		break;

Note that the option has to be an int, and the length has to be
that of an int as well.  Linux wants a `struct timeval'.  I wonder
if there's a standard in this area?

OK. Can you both try this alternate patch? It should be portable, and GDB shouldn't cause it to kick out. I've set it up so that for SSL-wrapped services it will timeout after 3 minutes, otherwise it uses the service-specific timeout.

--
Kenneth Murchison
Systems Programmer
Project Cyrus Developer/Maintainer
Carnegie Mellon University
Index: imapd.c
===================================================================
RCS file: /afs/andrew/system/cvs/src/cyrus/imap/imapd.c,v
retrieving revision 1.535
diff -u -r1.535 imapd.c
--- imapd.c	9 Nov 2007 12:54:22 -0000	1.535
+++ imapd.c	20 Nov 2007 14:15:24 -0000
@@ -148,6 +148,7 @@
 /* end PROXY STUFF */
 
 /* per-user/session state */
+int imapd_timeout;
 struct protstream *imapd_out = NULL;
 struct protstream *imapd_in = NULL;
 struct protgroup *protin = NULL;
@@ -701,7 +702,6 @@
 #endif
 {
     socklen_t salen;
-    int timeout;
     sasl_security_properties_t *secprops = NULL;
     struct sockaddr_storage imapd_localaddr, imapd_remoteaddr;
     char localip[60], remoteip[60];
@@ -778,9 +778,10 @@
     proc_register("imapd", imapd_clienthost, NULL, NULL);
 
     /* Set inactivity timer */
-    timeout = config_getint(IMAPOPT_TIMEOUT);
-    if (timeout < 30) timeout = 30;
-    prot_settimeout(imapd_in, timeout*60);
+    imapd_timeout = config_getint(IMAPOPT_TIMEOUT);
+    if (imapd_timeout < 30) imapd_timeout = 30;
+    imapd_timeout *= 60;
+    prot_settimeout(imapd_in, imapd_timeout);
     prot_setflushonread(imapd_in, imapd_out);
 
     /* we were connected on imaps port so we should do 
@@ -6626,6 +6627,7 @@
   
     result=tls_start_servertls(0, /* read */
 			       1, /* write */
+			       imaps ? 180 : imapd_timeout,
 			       layerp,
 			       &auth_id,
 			       &tls_conn);
Index: lmtpengine.c
===================================================================
RCS file: /afs/andrew/system/cvs/src/cyrus/imap/lmtpengine.c,v
retrieving revision 1.122
diff -u -r1.122 lmtpengine.c
--- lmtpengine.c	10 Oct 2007 15:14:39 -0000	1.122
+++ lmtpengine.c	20 Nov 2007 14:15:25 -0000
@@ -1579,6 +1579,7 @@
   
 		r=tls_start_servertls(0, /* read */
 				      1, /* write */
+				      360, /* 6 minutes */
 				      layerp,
 				      &auth_id,
 				      &(cd.tls_conn));
Index: mupdate.c
===================================================================
RCS file: /afs/andrew/system/cvs/src/cyrus/imap/mupdate.c,v
retrieving revision 1.99
diff -u -r1.99 mupdate.c
--- mupdate.c	10 Oct 2007 15:14:39 -0000	1.99
+++ mupdate.c	20 Nov 2007 14:15:25 -0000
@@ -1941,6 +1941,7 @@
   
     result=tls_start_servertls(C->pin->fd, /* read */
 			       C->pout->fd, /* write */
+			       180, /* 3 minutes */
 			       layerp,
 			       &auth_id,
 			       &C->tlsconn);
Index: nntpd.c
===================================================================
RCS file: /afs/andrew/system/cvs/src/cyrus/imap/nntpd.c,v
retrieving revision 1.60
diff -u -r1.60 nntpd.c
--- nntpd.c	10 Oct 2007 15:14:39 -0000	1.60
+++ nntpd.c	20 Nov 2007 14:15:25 -0000
@@ -142,6 +142,7 @@
 
 sasl_conn_t *nntp_saslconn; /* the sasl connection context */
 
+int nntp_timeout;
 char newsprefix[100] = "";
 char *nntp_userid = 0, *newsmaster;
 struct auth_state *nntp_authstate = 0, *newsmaster_authstate;
@@ -523,7 +524,6 @@
     char localip[60], remoteip[60];
     char hbuf[NI_MAXHOST];
     int niflags;
-    int timeout;
     sasl_security_properties_t *secprops=NULL;
     char unavail[1024];
 
@@ -590,9 +590,10 @@
     proc_register("nntpd", nntp_clienthost, NULL, NULL);
 
     /* Set inactivity timer */
-    timeout = config_getint(IMAPOPT_NNTPTIMEOUT);
-    if (timeout < 3) timeout = 3;
-    prot_settimeout(nntp_in, timeout*60);
+    nntp_timeout = config_getint(IMAPOPT_NNTPTIMEOUT);
+    if (nntp_timeout < 3) nntp_timeout = 3;
+    nntp_timeout *= 60;
+    prot_settimeout(nntp_in, nntp_timeout);
     prot_setflushonread(nntp_in, nntp_out);
 
     /* we were connected on nntps port so we should do 
@@ -4025,6 +4026,7 @@
   
     result=tls_start_servertls(0, /* read */
 			       1, /* write */
+			       nntps ? 180 : nntp_timeout,
 			       layerp,
 			       &auth_id,
 			       &tls_conn);
Index: pop3d.c
===================================================================
RCS file: /afs/andrew/system/cvs/src/cyrus/imap/pop3d.c,v
retrieving revision 1.181
diff -u -r1.181 pop3d.c
--- pop3d.c	19 Oct 2007 01:03:17 -0000	1.181
+++ pop3d.c	20 Nov 2007 14:15:25 -0000
@@ -112,6 +112,7 @@
 
 sasl_conn_t *popd_saslconn; /* the sasl connection context */
 
+int popd_timeout;
 char *popd_userid = 0, *popd_subfolder = 0;
 struct mailbox *popd_mailbox = 0;
 struct auth_state *popd_authstate = 0;
@@ -453,7 +454,6 @@
     char hbuf[NI_MAXHOST];
     char localip[60], remoteip[60];
     int niflags;
-    int timeout;
     sasl_security_properties_t *secprops=NULL;
 
     signals_poll();
@@ -517,9 +517,10 @@
     proc_register("pop3d", popd_clienthost, NULL, NULL);
 
     /* Set inactivity timer */
-    timeout = config_getint(IMAPOPT_POPTIMEOUT);
-    if (timeout < 10) timeout = 10;
-    prot_settimeout(popd_in, timeout*60);
+    popd_timeout = config_getint(IMAPOPT_POPTIMEOUT);
+    if (popd_timeout < 10) popd_timeout = 10;
+    popd_timeout *= 60;
+    prot_settimeout(popd_in, popd_timeout);
     prot_setflushonread(popd_in, popd_out);
 
     if (kflag) kpop();
@@ -1075,6 +1076,7 @@
   
     result=tls_start_servertls(0, /* read */
 			       1, /* write */
+			       pop3s ? 180 : popd_timeout,
 			       layerp,
 			       &auth_id,
 			       &tls_conn);
Index: sync_server.c
===================================================================
RCS file: /afs/andrew/system/cvs/src/cyrus/imap/sync_server.c,v
retrieving revision 1.18
diff -u -r1.18 sync_server.c
--- sync_server.c	10 Oct 2007 15:14:39 -0000	1.18
+++ sync_server.c	20 Nov 2007 14:15:26 -0000
@@ -1266,6 +1266,7 @@
   
     result=tls_start_servertls(0, /* read */
 			       1, /* write */
+			       180, /* 3 minutes */
 			       layerp,
 			       &auth_id,
 			       &tls_conn);
Index: tls.c
===================================================================
RCS file: /afs/andrew/system/cvs/src/cyrus/imap/tls.c,v
retrieving revision 1.59
diff -u -r1.59 tls.c
--- tls.c	5 Oct 2007 19:04:19 -0000	1.59
+++ tls.c	20 Nov 2007 14:15:26 -0000
@@ -118,6 +118,7 @@
 
 /* Application-specific. */
 #include "assert.h"
+#include "nonblock.h"
 #include "xmalloc.h"
 #include "xstrlcat.h"
 #include "xstrlcpy.h"
@@ -794,7 +795,7 @@
   * filled in if the client authenticated. 'ret' is the SSL connection
   * on success.
   */
-int tls_start_servertls(int readfd, int writefd,
+int tls_start_servertls(int readfd, int writefd, int timeout,
 			int *layerbits, char **authid, SSL **ret)
 {
     int     sts;
@@ -849,14 +850,40 @@
     if (var_imapd_tls_loglevel >= 3)
 	do_dump = 1;
 
-    if ((sts = SSL_accept(tls_conn)) <= 0) {
-	SSL_SESSION *session = SSL_get_session(tls_conn);
-	if (session) {
-	    SSL_CTX_remove_session(s_ctx, session);
+    nonblock(readfd, 1);
+    while (1) {
+	int err;
+
+	sts = SSL_accept(tls_conn);
+	err = SSL_get_error(tls_conn, sts);
+	if (err == SSL_ERROR_NONE) {
+	    syslog(LOG_DEBUG, "SSL_accept() succeeded -> done");
+	    break; /* ok -> done */
+	} else if (err == SSL_ERROR_SYSCALL &&
+		   (errno == EINTR || errno == EAGAIN)) {
+	    syslog(LOG_DEBUG, "SSL_accept() interrupted by signal -> retrying");
+	    continue; /* ok -> retry */
+	} else if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
+	    fd_set rfds;
+	    struct timeval tv;
+
+	    syslog(LOG_DEBUG, "SSL_accept() incomplete -> waiting");
+
+	    FD_ZERO(&rfds);
+	    FD_SET(readfd, &rfds);
+	    tv.tv_sec = timeout;
+	    tv.tv_usec = 0;
+
+	    sts = select(1, &rfds, NULL, NULL, &tv);
+	    if (sts > 0) continue; /* ok -> retry */
 	}
+
+	/* error or timeout */
+	syslog(LOG_DEBUG, "error or timeout in SSL_accept() -> done");
 	r = -1;
 	goto done;
     }
+
     /* Only loglevel==4 dumps everything */
     if (var_imapd_tls_loglevel < 4)
 	do_dump = 0;
@@ -939,8 +966,13 @@
     }
 
  done:
+    nonblock(readfd, 0);
     if (r && tls_conn) {
 	/* error; clean up */
+	SSL_SESSION *session = SSL_get_session(tls_conn);
+	if (session) {
+	    SSL_CTX_remove_session(s_ctx, session);
+	}
 	SSL_free(tls_conn);
 	tls_conn = NULL;
     }
Index: tls.h
===================================================================
RCS file: /afs/andrew/system/cvs/src/cyrus/imap/tls.h,v
retrieving revision 1.18
diff -u -r1.18 tls.h
--- tls.h	22 Oct 2003 18:50:09 -0000	1.18
+++ tls.h	20 Nov 2007 14:15:26 -0000
@@ -69,7 +69,7 @@
 			  char *var_tls_key_file);
 
 /* start tls negotiation */
-int tls_start_servertls(int readfd, int writefd, 
+int tls_start_servertls(int readfd, int writefd, int timeout,
 			int *layerbits, char **authid, SSL **ret);
 
 int tls_start_clienttls(int readfd, int writefd,
----
Cyrus Home Page: http://cyrusimap.web.cmu.edu/
Cyrus Wiki/FAQ: http://cyrusimap.web.cmu.edu/twiki
List Archives/Info: http://asg.web.cmu.edu/cyrus/mailing-list.html

[Index of Archives]     [Cyrus SASL]     [Squirrel Mail]     [Asterisk PBX]     [Video For Linux]     [Photo]     [Yosemite News]     [gtk]     [KDE]     [Gimp on Windows]     [Steve's Art]

  Powered by Linux