cmd-idle.c revision 7cb128dc4cae2a03a742f63ba7afee23c78e3af0
/* Copyright (c) 2002-2015 Dovecot authors, see the included COPYING file */
#include "imap-common.h"
#include "net.h"
#include "ioloop.h"
#include "istream.h"
#include "ostream.h"
#include "crc32.h"
#include "mail-storage-settings.h"
#include "imap-commands.h"
#include "imap-sync.h"
#include <stdlib.h>
struct cmd_idle_context {
struct client_command_context *cmd;
struct imap_sync_context *sync_ctx;
struct timeout *keepalive_to;
unsigned int manual_cork:1;
unsigned int sync_pending:1;
};
static void
{
/* we're here only in connection failure cases */
}
if (done_ok)
else
if (free_cmd)
}
static bool
{
const char *line;
else {
free_cmd);
return TRUE;
}
}
return FALSE;
}
{
case -1:
/* disconnected */
return;
case -2:
return;
}
/* we're still sending output to client. wait until it's all
sent so we don't lose any changes. */
return;
}
if (!client->disconnected)
}
}
{
if (client->disconnected)
}
{
/* it's busy sending output */
return;
}
Sending this also catches dead connections. Don't send
anything if there is already data waiting in output
buffer. */
}
/* Make sure idling connections don't get disconnected. There are
several clients that really want to IDLE forever and there's not
much harm in letting them do so. */
/* recalculate time for the next keepalive timeout */
}
{
}
{
else {
if (client->disconnected)
}
}
{
unsigned int addr;
return FALSE;
return FALSE; /* 10/8 */
return FALSE; /* 192.168/16 */
return FALSE; /* 172.16/12 */
return FALSE; /* 127/8 */
}
#ifdef HAVE_IPV6
return FALSE; /* fc00::/7 */
}
#endif
return TRUE;
}
{
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. */
}
{
return TRUE;
}
if (ctx->manual_cork) {
/* we're coming from idle_callback instead of a normal
I/O handler, so we'll have to do corking manually */
}
/* unfinished */
if (ctx->manual_cork) {
}
return FALSE;
}
}
}
if (ctx->sync_pending) {
/* more changes occurred while we were sending changes to
client */
/* NOTE: this recurses back to this function,
so we return here instead of doing everything twice. */
return FALSE;
}
if (ctx->manual_cork) {
}
return TRUE;
}
/* input is pending */
}
return FALSE;
}
{
struct cmd_idle_context *ctx;
/* check immediately if there are changes. if they came before we
added mailbox-notifier, we wouldn't see them otherwise. */
}