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