From 66b8dbd87cd25cfb50b980c0b2b532bffb3fff4e Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Wed, 30 Mar 2011 03:00:30 +0300 Subject: [PATCH] Send keep-alive packets Follows XChat-GNOME in sending a PING message after every 30s. Fixes: https://bugs.freedesktop.org/35058 --- src/idle-connection.c | 35 +++++++++++++++++++++++++++++++++++ 1 files changed, 35 insertions(+), 0 deletions(-) diff --git a/src/idle-connection.c b/src/idle-connection.c index 99ad92a..4c14525 100644 --- a/src/idle-connection.c +++ b/src/idle-connection.c @@ -22,6 +22,7 @@ #include +#include #include #include @@ -56,6 +57,8 @@ * be subject to this mechanism. */ +#define KEEP_ALIVE_TIMEOUT 30 + #define MSG_QUEUE_UNLOAD_AT_A_TIME 1 #define MSG_QUEUE_TIMEOUT 2 @@ -164,6 +167,9 @@ struct _IdleConnectionPrivate { /* UNIX time the last message was sent on */ time_t last_msg_sent; + /* GSource id for keep alive message timeout */ + guint keep_alive_timeout; + /* GSource id for message queue unloading timeout */ guint msg_queue_timeout; @@ -343,6 +349,11 @@ static void idle_connection_dispose (GObject *object) { priv->dispose_has_run = TRUE; + if (priv->keep_alive_timeout) { + g_source_remove(priv->keep_alive_timeout); + priv->keep_alive_timeout = 0; + } + if (priv->msg_queue_timeout) g_source_remove(priv->msg_queue_timeout); @@ -652,6 +663,7 @@ static void _start_connecting_continue(IdleConnection *conn) { irc_handshakes(conn); } +static gboolean keep_alive_timeout_cb(gpointer user_data); static gboolean msg_queue_timeout_cb(gpointer user_data); static void sconn_status_changed_cb(IdleServerConnectionIface *sconn, IdleServerConnectionState state, IdleServerConnectionStateReason reason, IdleConnection *conn) { @@ -699,6 +711,9 @@ static void sconn_status_changed_cb(IdleServerConnectionIface *sconn, IdleServer break; case SERVER_CONNECTION_STATE_CONNECTED: + if (priv->keep_alive_timeout == 0) + priv->keep_alive_timeout = g_timeout_add_seconds(KEEP_ALIVE_TIMEOUT, keep_alive_timeout_cb, conn); + if ((priv->msg_queue_timeout == 0) && (g_queue_get_length(priv->msg_queue) > 0)) { IDLE_DEBUG("we had messages in queue, start unloading them now"); @@ -723,6 +738,26 @@ static void sconn_received_cb(IdleServerConnectionIface *sconn, gchar *raw_msg, g_free(converted); } +static void _send_with_priority(IdleConnection *conn, const gchar *msg, guint priority); + +static gboolean keep_alive_timeout_cb(gpointer user_data) { + IdleConnection *conn = IDLE_CONNECTION(user_data); + IdleConnectionPrivate *priv = IDLE_CONNECTION_GET_PRIVATE(conn); + gchar cmd[IRC_MSG_MAXLEN + 1]; + gint64 ping_time; + + if (priv->sconn_status != SERVER_CONNECTION_STATE_CONNECTED) { + priv->keep_alive_timeout = 0; + return FALSE; + } + + ping_time = g_get_real_time(); + g_snprintf(cmd, IRC_MSG_MAXLEN + 1, "PING %" PRId64, ping_time); + _send_with_priority(conn, cmd, SERVER_CMD_MIN_PRIORITY); + + return TRUE; +} + static gboolean msg_queue_timeout_cb(gpointer user_data) { IdleConnection *conn = IDLE_CONNECTION(user_data); IdleConnectionPrivate *priv = IDLE_CONNECTION_GET_PRIVATE(conn); -- 1.7.4