[fetchmail-users] [PATCH] Re: possible bug in IMAP IDLE, connection times out after 30 minutes

Sunil Shetye shetye at bombay.retortsoft.com
Thu Dec 14 10:57:06 CET 2006


Quoting from Andrew Baumann's mail on Wed, Dec 13, 2006:
> >    The server MAY consider a client inactive if it has an IDLE command
> >    running, and if such a server has an inactivity timeout it MAY log
> >    the client off implicitly at the end of its timeout period.  Because
> >    of that, clients using IDLE are advised to terminate the IDLE and
> >    re-issue it at least every 29 minutes to avoid being logged off.
> >    This still allows a client to receive immediate mailbox updates even
> >    though it need only "poll" at half hour intervals.
> 
> I've had a quick look in the fetchmail source, and there is some code there 
> that claims to do something after 28 minutes, but it doesn't appear to be 
> working. Here is the syslog output of fetchmail running, that shows the 
> socket being closed 30 minutes after fetchmail last said anything:
> 
> Dec 10 16:24:30 zarquon fetchmail[28439]: IMAP> A0013 IDLE
> Dec 10 16:24:31 zarquon fetchmail[28439]: IMAP< + idling
> Dec 10 16:26:31 zarquon fetchmail[28439]: IMAP< * OK Still here

...

> Dec 10 16:52:32 zarquon fetchmail[28439]: IMAP< * OK Still here
> Dec 10 16:54:32 zarquon fetchmail[28439]: re-poll failed
> Dec 10 16:54:32 zarquon fetchmail[28439]: socket error while fetching from 
> andrewb at imap.cse.unsw.edu.au

The intermediate messages from the IMAP server are causing the timeout
to be reset. Please try this patch:

Index: fetchmail-6.3/imap.c
===================================================================
--- fetchmail-6.3/imap.c	(revision 4989)
+++ fetchmail-6.3/imap.c	(working copy)
@@ -46,7 +46,8 @@
 static int actual_deletions = 0;
 
 /* for "IMAP> IDLE" */
-static int saved_timeout = 0;
+static int saved_timeout = 0, idle_timeout = 0;
+static time_t idle_start_time = 0;
 
 static int imap_ok(int sock, char *argbuf)
 /* parse command response */
@@ -163,6 +164,15 @@
 		return(PS_LOCKBUSY);
 	    }
 	}
+
+	if (stage == STAGE_IDLE)
+	{
+	    /* reduce the timeout: servers may not reset their timeout
+	     * when they send some information asynchronously */
+	    mytimeout = idle_timeout - (time((time_t *) NULL) - idle_start_time);
+	    if (mytimeout <= 0)
+		return(PS_IDLETIMEOUT);
+	}
     } while
 	(tag[0] != '\0' && strncmp(buf, tag, strlen(tag)));
 
@@ -676,7 +686,8 @@
 	/* special timeout to terminate the IDLE and re-issue it
 	 * at least every 28 minutes:
 	 * (the server may have an inactivity timeout) */
-	mytimeout = 1680; /* 28 min */
+	mytimeout = idle_timeout = 1680; /* 28 min */
+	time(&idle_start_time);
 	stage = STAGE_IDLE;
 	/* enter IDLE mode */
 	ok = gen_transact(sock, "IDLE");
@@ -704,7 +715,8 @@
 	     * notification out of the blue. This is in compliance
 	     * with RFC 2060 section 5.3. Wait for that with a low
 	     * timeout */
-	    mytimeout = 28;
+	    mytimeout = idle_timeout = 28;
+	    time(&idle_start_time);
 	    stage = STAGE_IDLE;
 	    /* We are waiting for notification; no tag needed */
 	    tag[0] = '\0';
===================================================================

-- 
Sunil Shetye.



More information about the fetchmail-users mailing list