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. |