diff --git a/src/command/command.c b/src/command/command.c index 91c25131..36579990 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -1490,15 +1490,17 @@ static struct cmd_t command_defs[] = }, { "/autoping", - cmd_autoping, parse_args, 1, 1, &cons_autoping_setting, + cmd_autoping, parse_args, 2, 2, &cons_autoping_setting, CMD_TAGS( CMD_TAG_CONNECTION) CMD_SYN( - "/autoping ") + "/autoping set ", + "/autoping timeout ") CMD_DESC( "Set the interval between sending ping requests to the server to ensure the connection is kept alive.") CMD_ARGS( - { "", "Number of seconds between sending pings, a value of 0 disables autoping." }) + { "set ", "Number of seconds between sending pings, a value of 0 disables autoping." }, + { "timeout ", "Seconds to wait for autoping responses, after which the connection is considered broken." }) CMD_NOEXAMPLES }, @@ -1908,6 +1910,7 @@ static Autocomplete script_ac; static Autocomplete script_show_ac; static Autocomplete console_ac; static Autocomplete console_muc_ac; +static Autocomplete autoping_ac; /* * Initialise command autocompleter and history @@ -2401,6 +2404,10 @@ cmd_init(void) autocomplete_add(console_muc_ac, "all"); autocomplete_add(console_muc_ac, "first"); autocomplete_add(console_muc_ac, "none"); + + autoping_ac = autocomplete_new(); + autocomplete_add(autoping_ac, "set"); + autocomplete_add(autoping_ac, "timeout"); } void @@ -2480,6 +2487,7 @@ cmd_uninit(void) autocomplete_free(script_show_ac); autocomplete_free(console_ac); autocomplete_free(console_muc_ac); + autocomplete_free(autoping_ac); } gboolean @@ -2674,6 +2682,7 @@ cmd_reset_autocomplete(ProfWin *window) autocomplete_reset(tls_certpath_ac); autocomplete_reset(console_ac); autocomplete_reset(console_muc_ac); + autocomplete_reset(autoping_ac); autocomplete_reset(script_ac); if (script_show_ac) { autocomplete_free(script_show_ac); @@ -2892,8 +2901,8 @@ _cmd_complete_parameters(ProfWin *window, const char *const input) } } - gchar *cmds[] = { "/prefs", "/disco", "/close", "/room" }; - Autocomplete completers[] = { prefs_ac, disco_ac, close_ac, room_ac }; + gchar *cmds[] = { "/prefs", "/disco", "/close", "/room", "/autoping" }; + Autocomplete completers[] = { prefs_ac, disco_ac, close_ac, room_ac, autoping_ac }; for (i = 0; i < ARRAY_SIZE(cmds); i++) { result = autocomplete_param_with_ac(input, cmds[i], completers[i], TRUE); diff --git a/src/command/commands.c b/src/command/commands.c index 404db139..192f241d 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -4788,23 +4788,46 @@ cmd_reconnect(ProfWin *window, const char *const command, gchar **args) gboolean cmd_autoping(ProfWin *window, const char *const command, gchar **args) { - char *value = args[0]; + char *cmd = args[0]; + char *value = args[1]; - int intval = 0; - char *err_msg = NULL; - gboolean res = strtoi_range(value, &intval, 0, INT_MAX, &err_msg); - if (res) { - prefs_set_autoping(intval); - iq_set_autoping(intval); - if (intval == 0) { - cons_show("Autoping disabled.", intval); + if (g_strcmp0(cmd, "set") == 0) { + int intval = 0; + char *err_msg = NULL; + gboolean res = strtoi_range(value, &intval, 0, INT_MAX, &err_msg); + if (res) { + prefs_set_autoping(intval); + iq_set_autoping(intval); + if (intval == 0) { + cons_show("Autoping disabled."); + } else { + cons_show("Autoping interval set to %d seconds.", intval); + } } else { - cons_show("Autoping interval set to %d seconds.", intval); + cons_show(err_msg); + cons_bad_cmd_usage(command); + free(err_msg); } + + } else if (g_strcmp0(cmd, "timeout") == 0) { + int intval = 0; + char *err_msg = NULL; + gboolean res = strtoi_range(value, &intval, 0, INT_MAX, &err_msg); + if (res) { + prefs_set_autoping_timeout(intval); + if (intval == 0) { + cons_show("Autoping timeout disabled."); + } else { + cons_show("Autoping timeout set to %d seconds.", intval); + } + } else { + cons_show(err_msg); + cons_bad_cmd_usage(command); + free(err_msg); + } + } else { - cons_show(err_msg); cons_bad_cmd_usage(command); - free(err_msg); } return TRUE; diff --git a/src/config/preferences.c b/src/config/preferences.c index bf576864..8624921c 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -513,6 +513,23 @@ prefs_set_autoping(gint value) _save_prefs(); } +gint +prefs_get_autoping_timeout(void) +{ + if (!g_key_file_has_key(prefs, PREF_GROUP_CONNECTION, "autoping.timeout", NULL)) { + return 5; + } else { + return g_key_file_get_integer(prefs, PREF_GROUP_CONNECTION, "autoping.timeout", NULL); + } +} + +void +prefs_set_autoping_timeout(gint value) +{ + g_key_file_set_integer(prefs, PREF_GROUP_CONNECTION, "autoping.timeout", value); + _save_prefs(); +} + gint prefs_get_autoaway_time(void) { diff --git a/src/config/preferences.h b/src/config/preferences.h index 03d59e76..80ed2696 100644 --- a/src/config/preferences.h +++ b/src/config/preferences.h @@ -156,6 +156,8 @@ void prefs_set_reconnect(gint value); gint prefs_get_reconnect(void); void prefs_set_autoping(gint value); gint prefs_get_autoping(void); +void prefs_set_autoping_timeout(gint value); +gint prefs_get_autoping_timeout(void); gint prefs_get_inpblock(void); void prefs_set_inpblock(gint value); diff --git a/src/ui/console.c b/src/ui/console.c index 14487b7c..315e933c 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -1695,6 +1695,15 @@ cons_autoping_setting(void) } else { cons_show("Autoping interval (/autoping) : %d seconds", autoping_interval); } + + gint autoping_timeout = prefs_get_autoping_timeout(); + if (autoping_timeout == 0) { + cons_show("Autoping timeout (/autoping) : OFF"); + } else if (autoping_timeout == 1) { + cons_show("Autoping timeout (/autoping) : 1 second"); + } else { + cons_show("Autoping timeout (/autoping) : %d seconds", autoping_timeout); + } } void diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c index 5390197f..d72d10ca 100644 --- a/src/xmpp/connection.c +++ b/src/xmpp/connection.c @@ -202,7 +202,7 @@ jabber_connect_with_details(const char *const jid, const char *const passwd, con } void -jabber_ping_fail(void) +jabber_autoping_fail(void) { if (jabber_conn.conn_status == JABBER_CONNECTED) { log_info("Closing connection"); diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 1fa5ffcc..6ccce236 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -139,10 +139,11 @@ iq_autoping_check(void) gdouble elapsed = g_timer_elapsed(autoping_time, NULL); unsigned long seconds_elapsed = elapsed * 1.0; - log_debug("Autoping check: waiting, %u", seconds_elapsed); - if (seconds_elapsed > 5) { - // disconnect - jabber_ping_fail(); + gint timeout = prefs_get_autoping_timeout(); + if (timeout > 0 && seconds_elapsed >= timeout) { + cons_show("Autoping response timed out afer %u seconds.", timeout); + log_debug("Autoping check: timed out afer %u seconds, disconnecting", timeout); + jabber_autoping_fail(); autoping_wait = FALSE; g_timer_destroy(autoping_time); } diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 883c4f13..7e5e430e 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -144,7 +144,7 @@ jabber_conn_status_t jabber_connect_with_details(const char *const jid, const ch jabber_conn_status_t jabber_connect_with_account(const ProfAccount *const account); void jabber_disconnect(void); void jabber_shutdown(void); -void jabber_ping_fail(void); +void jabber_autoping_fail(void); void jabber_process_events(int millis); const char* jabber_get_fulljid(void); const char* jabber_get_domain(void);