aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2010-03-27 22:49:19 -0400
committerWilmer van der Gaast <wilmer@gaast.net>2010-03-27 22:49:19 -0400
commit3923003fb56f3b13eba1fa44c900175ae2574a1c (patch)
tree07f8a85c1837ff5b4af9cc4965ff72ea9565a6e1
parent6761a40af82d8134ee9fa2ac1d2b34475d297ad8 (diff)
Restored server-initiated PINGs.
-rw-r--r--irc.c41
-rw-r--r--irc_commands.c18
2 files changed, 48 insertions, 11 deletions
diff --git a/irc.c b/irc.c
index 72933fef..4eaa55a8 100644
--- a/irc.c
+++ b/irc.c
@@ -27,6 +27,7 @@
GSList *irc_connection_list;
+static gboolean irc_userping( gpointer _irc, gint fd, b_input_condition cond );
static char *set_eval_charset( set_t *set, char *value );
irc_t *irc_new( int fd )
@@ -86,8 +87,8 @@ irc_t *irc_new( int fd )
if( myhost == NULL )
myhost = g_strdup( "localhost.localdomain" );
- //if( global.conf->ping_interval > 0 && global.conf->ping_timeout > 0 )
- // irc->ping_source_id = b_timeout_add( global.conf->ping_interval * 1000, irc_userping, irc );
+ if( global.conf->ping_interval > 0 && global.conf->ping_timeout > 0 )
+ irc->ping_source_id = b_timeout_add( global.conf->ping_interval * 1000, irc_userping, irc );
irc_connection_list = g_slist_append( irc_connection_list, irc );
@@ -688,6 +689,42 @@ void irc_umode_set( irc_t *irc, const char *s, gboolean allow_priv )
}
+/* Returns 0 if everything seems to be okay, a number >0 when there was a
+ timeout. The number returned is the number of seconds we received no
+ pongs from the user. When not connected yet, we don't ping but drop the
+ connection when the user fails to connect in IRC_LOGIN_TIMEOUT secs. */
+static gboolean irc_userping( gpointer _irc, gint fd, b_input_condition cond )
+{
+ irc_t *irc = _irc;
+ int rv = 0;
+
+ if( !( irc->status & USTATUS_LOGGED_IN ) )
+ {
+ if( gettime() > ( irc->last_pong + IRC_LOGIN_TIMEOUT ) )
+ rv = gettime() - irc->last_pong;
+ }
+ else
+ {
+ if( ( gettime() > ( irc->last_pong + global.conf->ping_interval ) ) && !irc->pinging )
+ {
+ irc_write( irc, "PING :%s", IRC_PING_STRING );
+ irc->pinging = 1;
+ }
+ else if( gettime() > ( irc->last_pong + global.conf->ping_timeout ) )
+ {
+ rv = gettime() - irc->last_pong;
+ }
+ }
+
+ if( rv > 0 )
+ {
+ irc_abort( irc, 0, "Ping Timeout: %d seconds", rv );
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
static char *set_eval_charset( set_t *set, char *value )
{
diff --git a/irc_commands.c b/irc_commands.c
index e5c6a95f..858b5bdd 100644
--- a/irc_commands.c
+++ b/irc_commands.c
@@ -107,6 +107,14 @@ static void irc_cmd_ping( irc_t *irc, char **cmd )
irc->root->host, cmd[1]?cmd[1]:irc->root->host );
}
+static void irc_cmd_pong( irc_t *irc, char **cmd )
+{
+ /* We could check the value we get back from the user, but in
+ fact we don't care, we're just happy s/he's still alive. */
+ irc->last_pong = gettime();
+ irc->pinging = 0;
+}
+
static void irc_cmd_join( irc_t *irc, char **cmd )
{
irc_channel_t *ic;
@@ -516,14 +524,6 @@ static void irc_cmd_nickserv( irc_t *irc, char **cmd )
root_command( irc, cmd + 1 );
}
-static void irc_cmd_pong( irc_t *irc, char **cmd )
-{
- /* We could check the value we get back from the user, but in
- fact we don't care, we're just happy he's still alive. */
- irc->last_pong = gettime();
- irc->pinging = 0;
-}
-
static void irc_cmd_version( irc_t *irc, char **cmd )
{
irc_send_num( irc, 351, "bitlbee-%s. %s :%s/%s ", BITLBEE_VERSION, irc->myhost, ARCH, CPU );
@@ -567,6 +567,7 @@ static const command_t irc_commands[] = {
{ "nick", 1, irc_cmd_nick, 0 },
{ "quit", 0, irc_cmd_quit, 0 },
{ "ping", 0, irc_cmd_ping, 0 },
+ { "pong", 0, irc_cmd_pong, IRC_CMD_LOGGED_IN },
{ "join", 1, irc_cmd_join, IRC_CMD_LOGGED_IN },
{ "names", 1, irc_cmd_names, IRC_CMD_LOGGED_IN },
{ "part", 1, irc_cmd_part, IRC_CMD_LOGGED_IN },
@@ -587,7 +588,6 @@ static const command_t irc_commands[] = {
{ "away", 0, irc_cmd_away, IRC_CMD_LOGGED_IN },
{ "nickserv", 1, irc_cmd_nickserv, IRC_CMD_LOGGED_IN },
{ "ns", 1, irc_cmd_nickserv, IRC_CMD_LOGGED_IN },
- { "pong", 0, irc_cmd_pong, IRC_CMD_LOGGED_IN },
{ "version", 0, irc_cmd_version, IRC_CMD_LOGGED_IN },
{ "completions", 0, irc_cmd_completions, IRC_CMD_LOGGED_IN },
{ "die", 0, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER },