dovecot-2.2: imap IDLE: Time "still here" packet sends based on ...

dovecot at dovecot.org dovecot at dovecot.org
Thu Aug 23 21:49:26 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/8d7f9e2d726c
changeset: 14954:8d7f9e2d726c
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Aug 23 21:49:15 2012 +0300
description:
imap IDLE: Time "still here" packet sends based on client IP address if possible.

diffstat:

 src/imap/cmd-idle.c |  42 ++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 40 insertions(+), 2 deletions(-)

diffs (66 lines):

diff -r 9bda1b81c16c -r 8d7f9e2d726c src/imap/cmd-idle.c
--- a/src/imap/cmd-idle.c	Thu Aug 23 15:29:43 2012 +0300
+++ b/src/imap/cmd-idle.c	Thu Aug 23 21:49:15 2012 +0300
@@ -1,6 +1,7 @@
 /* Copyright (c) 2002-2012 Dovecot authors, see the included COPYING file */
 
 #include "imap-common.h"
+#include "network.h"
 #include "ioloop.h"
 #include "istream.h"
 #include "ostream.h"
@@ -160,15 +161,52 @@
 	}
 }
 
+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) {
+		addr = ip->u.ip4.s_addr;
+		if (addr >= 167772160 && addr <= 184549375)
+			return FALSE; /* 10/8 */
+		if (addr >= 3232235520 && addr <= 3232301055)
+			return FALSE; /* 192.168/16 */
+		if (addr >= 2130706432 && addr <= 2147483647)
+			return FALSE; /* 127/8 */
+	}
+	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;
 
-	interval -= (time(NULL) +
-		     crc32_str(ctx->client->user->username)) % interval;
+	/* 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 = 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;
 
 	if (ctx->keepalive_to != NULL)
 		timeout_remove(&ctx->keepalive_to);


More information about the dovecot-cvs mailing list