|
From: Sunil S. <sh...@bo...> - 2006-12-14 10:58:04
|
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
> an...@im...
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.
|