ZyklonB: add connection timeouts
This commit is contained in:
parent
19c170a7aa
commit
479da40a3d
39
zyklonb.c
39
zyklonb.c
@ -204,8 +204,6 @@ try_finish_quit (struct bot_context *ctx)
|
|||||||
static bool irc_send (struct bot_context *ctx,
|
static bool irc_send (struct bot_context *ctx,
|
||||||
const char *format, ...) ATTRIBUTE_PRINTF (2, 3);
|
const char *format, ...) ATTRIBUTE_PRINTF (2, 3);
|
||||||
|
|
||||||
// XXX: is it okay to just ignore the return value and wait until we receive
|
|
||||||
// it in on_irc_readable()?
|
|
||||||
static bool
|
static bool
|
||||||
irc_send (struct bot_context *ctx, const char *format, ...)
|
irc_send (struct bot_context *ctx, const char *format, ...)
|
||||||
{
|
{
|
||||||
@ -1469,6 +1467,36 @@ on_irc_disconnected (struct bot_context *ctx)
|
|||||||
irc_try_reconnect (ctx);
|
irc_try_reconnect (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_irc_ping_timeout (void *user_data)
|
||||||
|
{
|
||||||
|
struct bot_context *ctx = user_data;
|
||||||
|
print_error ("connection timeout");
|
||||||
|
on_irc_disconnected (ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_irc_timeout (void *user_data)
|
||||||
|
{
|
||||||
|
// Provoke a response from the server
|
||||||
|
struct bot_context *ctx = user_data;
|
||||||
|
irc_send (ctx, "PING :%s", str_map_find (&ctx->config, "nickname"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
irc_reset_timeouts (struct bot_context *ctx)
|
||||||
|
{
|
||||||
|
ssize_t i;
|
||||||
|
struct poller_timers *timers = &ctx->poller.timers;
|
||||||
|
while ((i = poller_timers_find_by_data (timers, ctx)) != -1)
|
||||||
|
poller_timers_remove_at_index (timers, i);
|
||||||
|
|
||||||
|
poller_timers_add (&ctx->poller.timers,
|
||||||
|
on_irc_timeout, ctx, 3 * 60 * 1000);
|
||||||
|
poller_timers_add (&ctx->poller.timers,
|
||||||
|
on_irc_ping_timeout, ctx, (3 * 60 + 30) * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_irc_readable (const struct pollfd *fd, struct bot_context *ctx)
|
on_irc_readable (const struct pollfd *fd, struct bot_context *ctx)
|
||||||
{
|
{
|
||||||
@ -1515,6 +1543,8 @@ end:
|
|||||||
|
|
||||||
if (disconnected)
|
if (disconnected)
|
||||||
on_irc_disconnected (ctx);
|
on_irc_disconnected (ctx);
|
||||||
|
else
|
||||||
|
irc_reset_timeouts (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -1550,16 +1580,13 @@ irc_connect (struct bot_context *ctx, struct error **e)
|
|||||||
if (!irc_establish_connection (ctx, irc_host, irc_port, use_ssl, e))
|
if (!irc_establish_connection (ctx, irc_host, irc_port, use_ssl, e))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// TODO: set a timeout on the socket, something like 30 minutes, then we
|
|
||||||
// should ideally send a PING... or just forcefully reconnect.
|
|
||||||
//
|
|
||||||
// TODO: in exec try: 1/ set blocking, 2/ setsockopt() SO_LINGER,
|
// TODO: in exec try: 1/ set blocking, 2/ setsockopt() SO_LINGER,
|
||||||
// (struct linger) { .l_onoff = true; .l_linger = 1 /* 1s should do */; }
|
// (struct linger) { .l_onoff = true; .l_linger = 1 /* 1s should do */; }
|
||||||
// 3/ /* O_CLOEXEC */ But only if the QUIT message proves unreliable.
|
// 3/ /* O_CLOEXEC */ But only if the QUIT message proves unreliable.
|
||||||
poller_set (&ctx->poller, ctx->irc_fd, POLLIN,
|
poller_set (&ctx->poller, ctx->irc_fd, POLLIN,
|
||||||
(poller_dispatcher_func) on_irc_readable, ctx);
|
(poller_dispatcher_func) on_irc_readable, ctx);
|
||||||
|
irc_reset_timeouts (ctx);
|
||||||
|
|
||||||
// TODO: probably check for errors from these calls as well
|
|
||||||
irc_send (ctx, "NICK %s", nickname);
|
irc_send (ctx, "NICK %s", nickname);
|
||||||
irc_send (ctx, "USER %s 8 * :%s", username, realname);
|
irc_send (ctx, "USER %s 8 * :%s", username, realname);
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user