dovecot-2.2: imap: Code cleanup: Moved IDLE keepalive timer calc...

dovecot at dovecot.org dovecot at dovecot.org
Sat Apr 25 08:28:54 UTC 2015


details:   http://hg.dovecot.org/dovecot-2.2/rev/25c848f10517
changeset: 18482:25c848f10517
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Apr 25 11:27:17 2015 +0300
description:
imap: Code cleanup: Moved IDLE keepalive timer calculation to lib-imap.

diffstat:

 src/imap/cmd-idle.c           |  58 +++---------------------------------------
 src/lib-imap/Makefile.am      |   2 +
 src/lib-imap/imap-keepalive.c |  49 ++++++++++++++++++++++++++++++++++++
 src/lib-imap/imap-keepalive.h |  24 +++++++++++++++++
 4 files changed, 80 insertions(+), 53 deletions(-)

diffs (185 lines):

diff -r 21a2ce6f8f37 -r 25c848f10517 src/imap/cmd-idle.c
--- a/src/imap/cmd-idle.c	Sat Apr 25 11:23:00 2015 +0300
+++ b/src/imap/cmd-idle.c	Sat Apr 25 11:27:17 2015 +0300
@@ -8,6 +8,7 @@
 #include "crc32.h"
 #include "mail-storage-settings.h"
 #include "imap-commands.h"
+#include "imap-keepalive.h"
 #include "imap-sync.h"
 
 #include <stdlib.h>
@@ -161,69 +162,20 @@
 	}
 }
 
-static bool remote_ip_is_usable(const struct ip_addr *ip)
-{
-	unsigned int addr;
-
-	if (ip->family == 0)
-		return FALSE;
-	if (ip->family == AF_INET) {
-#define IP4(a,b,c,d) ((unsigned)(a)<<24|(unsigned)(b)<<16|(unsigned)(c)<<8|(unsigned)(d))
-		addr = ip->u.ip4.s_addr;
-		if (addr >= IP4(10,0,0,0) && addr <= IP4(10,255,255,255))
-			return FALSE; /* 10/8 */
-		if (addr >= IP4(192,168,0,0) && addr <= IP4(192,168,255,255))
-			return FALSE; /* 192.168/16 */
-		if (addr >= IP4(172,16,0,0) && addr <= IP4(172,31,255,255))
-			return FALSE; /* 172.16/12 */
-		if (addr >= IP4(127,0,0,0) && addr <= IP4(127,255,255,255))
-			return FALSE; /* 127/8 */
-#undef IP4
-	}
-#ifdef HAVE_IPV6
-	else if (ip->family == AF_INET6) {
-		addr = ip->u.ip6.s6_addr[0];
-		if (addr == 0xfc || addr == 0xfd)
-			return FALSE; /* fc00::/7 */
-	}
-#endif
-	return TRUE;
-}
-
 static void idle_add_keepalive_timeout(struct cmd_idle_context *ctx)
 {
 	unsigned int interval = ctx->client->set->imap_idle_notify_interval;
-	unsigned int client_hash;
 
 	if (interval == 0)
 		return;
 
-	/* set the interval so that the client gets the keepalive notifications
-	   at exactly the same time for all the connections. this helps to
-	   reduce battery usage in mobile devices. but we don't really want to
-	   send this notification for everyone at the same time, because it
-	   would cause huge peaks of activity.
-
-	   basing the notifications on the username works well for one account,
-	   but basing it on the IP address allows the client to get all of the
-	   notifications at the same time for multiple accounts as well (of
-	   course assuming Dovecot is running on all the servers :)
-
-	   one potential downside to using IP is that if a proxy hides the
-	   client's IP address notifications are sent to everyone at the same
-	   time, but this can be avoided by using a properly configured Dovecot
-	   proxy. we'll also try to avoid this by not doing it for the commonly
-	   used intranet IP ranges. */
-	client_hash = ctx->client->user->remote_ip != NULL &&
-		remote_ip_is_usable(ctx->client->user->remote_ip) ?
-		net_ip_hash(ctx->client->user->remote_ip) :
-		crc32_str(ctx->client->user->username);
-	interval -= (time(NULL) + client_hash) % interval;
+	interval = imap_keepalive_interval_msecs(ctx->client->user->username,
+						 ctx->client->user->remote_ip,
+						 interval);
 
 	if (ctx->keepalive_to != NULL)
 		timeout_remove(&ctx->keepalive_to);
-	ctx->keepalive_to = timeout_add(interval * 1000,
-					keepalive_timeout, ctx);
+	ctx->keepalive_to = timeout_add(interval, keepalive_timeout, ctx);
 }
 
 static bool cmd_idle_continue(struct client_command_context *cmd)
diff -r 21a2ce6f8f37 -r 25c848f10517 src/lib-imap/Makefile.am
--- a/src/lib-imap/Makefile.am	Sat Apr 25 11:23:00 2015 +0300
+++ b/src/lib-imap/Makefile.am	Sat Apr 25 11:27:17 2015 +0300
@@ -13,6 +13,7 @@
 	imap-date.c \
 	imap-envelope.c \
 	imap-id.c \
+	imap-keepalive.c \
 	imap-match.c \
 	imap-parser.c \
 	imap-quote.c \
@@ -28,6 +29,7 @@
 	imap-date.h \
 	imap-envelope.h \
 	imap-id.h \
+	imap-keepalive.h \
 	imap-match.h \
 	imap-parser.h \
 	imap-resp-code.h \
diff -r 21a2ce6f8f37 -r 25c848f10517 src/lib-imap/imap-keepalive.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-imap/imap-keepalive.c	Sat Apr 25 11:27:17 2015 +0300
@@ -0,0 +1,49 @@
+/* Copyright (c) 2002-2014 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "crc32.h"
+#include "net.h"
+#include "imap-keepalive.h"
+
+#include <time.h>
+
+static bool imap_remote_ip_is_usable(const struct ip_addr *ip)
+{
+	unsigned int addr;
+
+	if (ip->family == 0)
+		return FALSE;
+	if (ip->family == AF_INET) {
+#define IP4(a,b,c,d) ((unsigned)(a)<<24|(unsigned)(b)<<16|(unsigned)(c)<<8|(unsigned)(d))
+		addr = ip->u.ip4.s_addr;
+		if (addr >= IP4(10,0,0,0) && addr <= IP4(10,255,255,255))
+			return FALSE; /* 10/8 */
+		if (addr >= IP4(192,168,0,0) && addr <= IP4(192,168,255,255))
+			return FALSE; /* 192.168/16 */
+		if (addr >= IP4(172,16,0,0) && addr <= IP4(172,31,255,255))
+			return FALSE; /* 172.16/12 */
+		if (addr >= IP4(127,0,0,0) && addr <= IP4(127,255,255,255))
+			return FALSE; /* 127/8 */
+#undef IP4
+	}
+#ifdef HAVE_IPV6
+	else if (ip->family == AF_INET6) {
+		addr = ip->u.ip6.s6_addr[0];
+		if (addr == 0xfc || addr == 0xfd)
+			return FALSE; /* fc00::/7 */
+	}
+#endif
+	return TRUE;
+}
+
+unsigned int
+imap_keepalive_interval_msecs(const char *username, const struct ip_addr *ip,
+			      unsigned int interval_secs)
+{
+	unsigned int client_hash;
+
+	client_hash = imap_remote_ip_is_usable(ip) ?
+		net_ip_hash(ip) : crc32_str(username);
+	interval_secs -= (time(NULL) + client_hash) % interval_secs;
+	return interval_secs * 1000;
+}
diff -r 21a2ce6f8f37 -r 25c848f10517 src/lib-imap/imap-keepalive.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-imap/imap-keepalive.h	Sat Apr 25 11:27:17 2015 +0300
@@ -0,0 +1,24 @@
+#ifndef IMAP_KEEPALIVE_H
+#define IMAP_KEEPALIVE_H
+
+/* This function can be used to set IMAP IDLE keepalive notification timeout
+   interval so that the client gets the keepalive notifications at exactly the
+   same time for all the IMAP connections. This helps to reduce battery usage
+   in mobile devices.
+
+   One problem with this is that we don't really want to send the notifications
+   to everyone at the same time, because it would cause huge peaks of activity.
+   Basing the notifications on the username works well for one account, but
+   basing it on the IP address allows the client to get all of the
+   notifications at the same time for multiple accounts as well (of course
+   assuming Dovecot is running on all the servers :)
+
+   One potential downside to using IP is that if a proxy hides the client's IP
+   address, the notifications are sent to everyone at the same time. This can
+   be avoided by using a properly configured Dovecot proxy, but we'll also try
+   to avoid this by not doing it for the commonly used intranet IP ranges. */
+unsigned int
+imap_keepalive_interval_msecs(const char *username, const struct ip_addr *ip,
+			      unsigned int interval_secs);
+
+#endif


More information about the dovecot-cvs mailing list