diff options
-rw-r--r-- | src/profanity.c | 1 | ||||
-rw-r--r-- | src/xmpp/connection.c | 63 | ||||
-rw-r--r-- | src/xmpp/iq.c | 25 | ||||
-rw-r--r-- | src/xmpp/xmpp.h | 3 | ||||
-rw-r--r-- | tests/unittests/xmpp/stub_xmpp.c | 1 |
5 files changed, 81 insertions, 12 deletions
diff --git a/src/profanity.c b/src/profanity.c index 6e973a72..51609582 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -124,6 +124,7 @@ prof_run(char *log_level, char *account_name) #endif notify_remind(); jabber_process_events(10); + iq_autoping_check(); ui_update(); } } diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c index 42293c18..5390197f 100644 --- a/src/xmpp/connection.c +++ b/src/xmpp/connection.c @@ -104,7 +104,7 @@ static jabber_conn_status_t _jabber_connect(const char *const fulljid, const cha const char *const altdomain, int port, const char *const tls_policy); static void _jabber_reconnect(void); - +static void _jabber_lost_connection(void); static void _connection_handler(xmpp_conn_t *const conn, const xmpp_conn_event_t status, const int error, xmpp_stream_error_t *const stream_error, void *const userdata); @@ -202,6 +202,35 @@ jabber_connect_with_details(const char *const jid, const char *const passwd, con } void +jabber_ping_fail(void) +{ + if (jabber_conn.conn_status == JABBER_CONNECTED) { + log_info("Closing connection"); + accounts_set_last_activity(jabber_get_account_name()); + jabber_conn.conn_status = JABBER_DISCONNECTING; + xmpp_disconnect(jabber_conn.conn); + + while (jabber_get_connection_status() == JABBER_DISCONNECTING) { + jabber_process_events(10); + } + if (jabber_conn.conn) { + xmpp_conn_release(jabber_conn.conn); + jabber_conn.conn = NULL; + } + if (jabber_conn.ctx) { + xmpp_ctx_free(jabber_conn.ctx); + jabber_conn.ctx = NULL; + } + } + + FREE_SET_NULL(jabber_conn.presence_message); + FREE_SET_NULL(jabber_conn.domain); + + jabber_conn.conn_status = JABBER_DISCONNECTED; + _jabber_lost_connection(); +} + +void jabber_disconnect(void) { // if connected, send end stream and wait for response @@ -281,6 +310,12 @@ jabber_get_connection_status(void) return (jabber_conn.conn_status); } +void +jabber_set_connection_status(jabber_conn_status_t status) +{ + jabber_conn.conn_status = status; +} + xmpp_conn_t* connection_get_conn(void) { @@ -543,6 +578,20 @@ _jabber_reconnect(void) } static void +_jabber_lost_connection(void) +{ + sv_ev_lost_connection(); + if (prefs_get_reconnect() != 0) { + assert(reconnect_timer == NULL); + reconnect_timer = g_timer_new(); + } else { + _connection_free_saved_account(); + _connection_free_saved_details(); + } + _connection_free_session_data(); +} + +static void _connection_handler(xmpp_conn_t *const conn, const xmpp_conn_event_t status, const int error, xmpp_stream_error_t *const stream_error, void *const userdata) { @@ -600,17 +649,7 @@ _connection_handler(xmpp_conn_t *const conn, const xmpp_conn_event_t status, con // lost connection for unknown reason if (jabber_conn.conn_status == JABBER_CONNECTED) { log_debug("Connection handler: Lost connection for unknown reason"); - sv_ev_lost_connection(); - if (prefs_get_reconnect() != 0) { - assert(reconnect_timer == NULL); - reconnect_timer = g_timer_new(); - // free resources but leave saved_user untouched - _connection_free_session_data(); - } else { - _connection_free_saved_account(); - _connection_free_saved_details(); - _connection_free_session_data(); - } + _jabber_lost_connection(); // login attempt failed } else if (jabber_conn.conn_status != JABBER_DISCONNECTING) { diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index dc1bbc4a..1fa5ffcc 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -99,6 +99,7 @@ static int _caps_response_handler_for_jid(xmpp_conn_t *const conn, xmpp_stanza_t static int _caps_response_handler_legacy(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata); static gboolean autoping_wait = FALSE; +static GTimer *autoping_time; void iq_add_handlers(void) @@ -126,6 +127,28 @@ iq_add_handlers(void) } void +iq_autoping_check(void) +{ + if (jabber_get_connection_status() != JABBER_CONNECTED) { + return; + } + + if (autoping_wait == FALSE) { + return; + } + + 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(); + autoping_wait = FALSE; + g_timer_destroy(autoping_time); + } +} + +void iq_set_autoping(const int seconds) { if (jabber_get_connection_status() != JABBER_CONNECTED) { @@ -529,6 +552,7 @@ static int _auto_pong_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata) { autoping_wait = FALSE; + g_timer_destroy(autoping_time); char *id = xmpp_stanza_get_id(stanza); if (id == NULL) { @@ -870,6 +894,7 @@ _autoping_timed_handler(xmpp_conn_t *const conn, void *const userdata) xmpp_send(conn, iq); xmpp_stanza_release(iq); autoping_wait = TRUE; + autoping_time = g_timer_new(); return 1; } diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index f52603eb..883c4f13 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -144,10 +144,12 @@ 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_process_events(int millis); const char* jabber_get_fulljid(void); const char* jabber_get_domain(void); jabber_conn_status_t jabber_get_connection_status(void); +void jabber_set_connection_status(jabber_conn_status_t status); char* jabber_get_presence_message(void); char* jabber_get_account_name(void); GList* jabber_get_available_resources(void); @@ -212,6 +214,7 @@ void iq_room_affiliation_set(const char *const room, const char *const jid, char void iq_room_kick_occupant(const char *const room, const char *const nick, const char *const reason); void iq_room_role_set(const char *const room, const char *const nick, char *role, const char *const reason); void iq_room_role_list(const char * const room, char *role); +void iq_autoping_check(void); // caps functions Capabilities* caps_lookup(const char *const jid); diff --git a/tests/unittests/xmpp/stub_xmpp.c b/tests/unittests/xmpp/stub_xmpp.c index 6abec1bf..dc630198 100644 --- a/tests/unittests/xmpp/stub_xmpp.c +++ b/tests/unittests/xmpp/stub_xmpp.c @@ -173,6 +173,7 @@ void iq_room_role_set(const char * const room, const char * const nick, char *ro const char * const reason) {} void iq_room_role_list(const char * const room, char *role) {} void iq_last_activity_request(gchar *jid) {} +void iq_autoping_check(void) {} // caps functions Capabilities* caps_lookup(const char * const jid) |