diff options
-rw-r--r-- | irc.c | 41 | ||||
-rw-r--r-- | irc_commands.c | 18 |
2 files changed, 48 insertions, 11 deletions
@@ -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 }, |